(for completeness)
While @enzotib's answer is most probably what you want, it's not what you asked for. [ -t 1 ]
checks if the file descriptor is a terminal device, not that it's anything other than a pipe (like a regular file, a socket, an other type of device like /dev/null
...)
The [
command has no equivalent of -t
but for pipes. To get the type of the file associated with a file descriptor, you need to perform the fstat()
system call on it. There's no standard command to do that, but some systems or shells have some.
With 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
}
Or with zsh
and its own stat
builtin (which predates GNU's one by a few years), here loaded as zstat
only:
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
}
Now a few notes:
It's not only shell pipelines that use pipes.
var=$(grep foo bar)
or:
cmd <(grep foo bar)
or:
coproc grep foo bar
also run grep
with its stdout going to a pipe.
If your shell is ksh93
, note that on some systems, it uses socketpairs instead of pipes in its pipelines.
[[ -t 0 && -t 1 ]]
if you only want line numbers if both standard input and standard output are connected to a terminal. – Gilles 'SO- stop being evil' Nov 28 '11 at 17:20