Grep alias - line numbers unless it's in a pipeline
You could use a function in bash (or any POSIX shell) like this:
grep() {
if [ -t 1 ] && [ -t 0 ]; then
command grep -n "$@"
else
command grep "$@"
fi
}
The [ -t 1 ]
part uses the [
command (also known as test
) to check if stdout is associated with a tty.
The [ -t 0 ]
checks standard input, as well, since you specified to only add line numbers if grep
is the only command in the pipeline.
(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.