Answers:
(为了完整性)
尽管@enzotib的答案很可能是您想要的,但并非您所要的。[ -t 1 ]
检查文件描述符是否是终端设备,而不是管道以外的其他设备(例如常规文件,套接字,其他类型的设备,例如/dev/null
...)
该[
命令-t
只对管道有效。要获取与文件描述符关联的文件的类型,您需要对其执行fstat()
系统调用。没有标准命令可以执行此操作,但是某些系统或Shell包含一些命令。
使用GNU stat
:
grep() {
if { [ "$(LC_ALL=C stat -c %F - <&3)" = fifo ]; } 3>&1 ||
[ "$(LC_ALL=C stat -c %F -)" = fifo ]; then
command grep "$@"
else
command grep -n "$@"
fi
}
或with zsh
和它自己的stat
内建函数(比GNU的内置函数早几年),在这里zstat
仅作为加载:
grep() {
zmodload -F zsh/stat b:zstat
local stdin_type stdout_type
if zstat -A stdin_type -s -f 0 +mode &&
zstat -A stdout_type -s -f 1 +mode &&
[[ $stdin_type = p* || $stdout_type = p* ]]
then
command grep "$@"
else
command grep -n "$@"
fi
}
现在几点注意事项:
使用管道的不仅是外壳管道。
var=$(grep foo bar)
要么:
cmd <(grep foo bar)
要么:
coproc grep foo bar
还可以grep
通过其stdout进入管道。
如果您的shell是ksh93
,请注意,在某些系统上,它使用套接字对而不是其管道中的管道。
[[ -t 0 && -t 1 ]]
如果仅在标准输入和标准输出都连接到端子的情况下只需要行号,则进行测试。