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.