理想情况下,这可以在shell中编写脚本,但是Perl或者Python也可以。 C代码可能会有帮助,但可能会失败成本/收益。
我认识到,redirect到一个FIFO(命名pipe道)可能是无法区分的真正的pipe道,这是足够的边缘情况下,我真的不在乎。
严格的POSIX解决scheme是最好的,UNIX / Linux变体独立是次佳,但至less在达尔文(MacOS X)上工作的东西是我现在需要的。
在你写答案之前 – 我已经知道test -t
– 它会告诉我stdout是否是一个terminal(在这种情况下,它绝对不是一个pipe道 – 但它不会告诉我stdout是否已被redirect到一个文件, – terminal字符设备,或UNIX域套接字而不是pipe道。
预期用例:我有一个应该在shell中的反引号内运行的命令,以便它可以输出设置环境variables的命令。 如果stdout没有被redirect到一个pipe道,我想这个命令会中止一个错误,因为在这种情况下,它肯定不会被eval `mycommand`;
调用eval `mycommand`;
。
如果在反引号内运行一个命令时shell会设置一些特殊的环境variables会很有帮助,但是由于它可能是bash或zsh之类的东西,所以pipe道检测更重要。
(我的评论转向按Alex Dupuy的建议回答)既然你说过你可以使用perl,我想你可以使用它的-p文件测试运算符( perldoc.perl.org/functions/-X.html ); 像perl -e 'exit(-p STDOUT ? 0 : 1);'
会告诉你,如果标准输出管道或先锋( 没有区分他们)。
Fwiw,从shell调用正是我使用perl -e
的原因:)
您可以对fstat
执行fstat
并检查返回的结构,例如, st_mode
= 0x1000(S_IFIFO)表示命名管道。
Python的例子:
from __future__ import print_function import sys import os print(os.fstat(sys.stdout.fileno()), file=sys.stderr)
在窗口输出:
C:> python test_fd.py | more nt.stat_result(st_mode=4096, st_ino=0L, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=0L, st_atime=0L, st_mtime=0L, st_ctime=0L) C:> python test_fd.py > test_fd.txt nt.stat_result(st_mode=33206, st_ino=16888498602769633L, st_dev=0, st_nlink=1, st_uid=0, st_gid=0, st_size=0L, st_atime= 1401119520L, st_mtime=1401119520L, st_ctime=1401119349L)
stat
命令适用于MacOS X以及其他Linux / Unix版本的变体实现,所以对我来说这是一个解决方案:
FORMOPT= TYPEFORM= stat() { if [ -z "$FORMOPT" ]; then if /usr/bin/stat --version >/dev/null 2>&1; then FORMOPT=--format TYPEFORM=%F else FORMOPT=-f TYPEFORM=%HT fi fi case $1 in type) FORMARG="$FORMOPT $TYPEFORM" ; shift ;; esac /usr/bin/stat -L $FORMARG "$@" } exec 9>&1 case `stat type /dev/fd/9` in [Ff]ifo*) echo stdout is a pipe ;; *) echo stdout is not a pipe ;; esac
有一个Linux特定的解决方案,做我想要的:
exec 9>&1 case `readlink /dev/fd/9` in pipe:\[*\]) echo stdout is a pipe ;; *) echo stdout is not a pipe ;; esac
但这不是我正在寻找的答案,因为我希望这个在xBSD上运行。
我已经做了这个答案社区wiki,所以随时可以改进它,但如果你有一个非Linux的解决方案(或使用其他技术的Linux特定的解决方案),请创建一个新的答案。
在Python中:
import sys print sys.stdout.isatty()
例子:
$ ./a True $ ./a | less False