How can I detect if my shell script is running through a pipe?

bash, pipe, shell

Solution

In a pure POSIX shell,

if [ -t 1 ] ; then echo terminal; else echo "not a terminal"; fi

returns "terminal", because the output is sent to your terminal, whereas

(if [ -t 1 ] ; then echo terminal; else echo "not a terminal"; fi) | cat

returns "not a terminal", because the output of the parenthetic element is piped to `cat`.

The `-t` flag is described in man pages as

-t fd True if file descriptor fd is open and refers to a terminal.

... where `fd` can be one of the usual file descriptor assignments:

- 0: standard input

- 1: standard output

- 2: standard error

Problem

How do I detect from within a shell script if its standard output is being sent to a terminal or if it's piped to another process? The case in point: I'd like to add escape codes to colorize output, but only when run interactively, but not when piped, similar to what `ls --color` does.

Original source