理想情况下,这可以在shell中编写脚本,但Perl或Python可以。 C代码可能会有所帮助,但可能会降低成本/收益。
我认识到重定向到FIFO(命名管道)可能与真实管道无法区分, 这就是我不太关心的边缘案例。
严格的POSIX解决方案是最好的,独立于UNIX / Linux变体是最好的,但至少在Darwin(MacOS X)上运行的东西是我现在需要的。
在你写答案之前 - I already know about test -t
- 这将告诉我stdout是否是一个终端(在这种情况下它绝对不是一个管道 - 但它不会告诉我stdout是否已被重定向到一个文件,非终端字符设备,或UNIX域套接字而不是管道。
预期用例:我有一个命令应该在shell的反引号中运行,
这样它就可以输出设置环境变量的命令。
如果stdout没有重定向到管道,我希望命令中止错误
因为在这种情况下它绝对没有被eval `mycommand`;
调用。
如果在反引号中运行命令时shell会设置一些特殊的环境变量会有所帮助,但由于它可能特定于bash或zsh或其他东西,因此管道检测更为重要
答案 0 :(得分:3)
您可以对文件描述符执行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)
Windows上的输出:
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)
答案 1 :(得分:1)
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
答案 2 :(得分:1)
(我的评论根据Alex Dupuy的建议转而回答)
既然你说你可以使用perl,我想你可以使用它的-p文件测试运算符(perldoc.perl.org/functions/-X.html);像perl -e 'exit(-p STDOUT ? 0 : 1);'
这样的东西会告诉你stdout是管道还是fifo(没有区分它们)。
Fwiw,从shell调用它正是我使用perl -e
的原因:))
答案 3 :(得分:1)
在Python中:
import sys
print sys.stdout.isatty()
示例:
$ ./a
True
$ ./a | less
False
答案 4 :(得分:0)
是一个特定于Linux的解决方案,可以满足我的需求:
exec 9>&1
case `readlink /dev/fd/9` in
pipe:\[*\]) echo stdout is a pipe ;;
*) echo stdout is not a pipe ;;
esac
但这不是我要找的答案,因为我希望它也可以在xBSD上运行。
我已经制作了这个答案社区维基,所以随时改进它, 但如果您有非Linux解决方案(或使用其他技术的特定于Linux的解决方案), 请创建一个新答案。