When you use git it seems to magically know whether standard out is going through a pipe or into a file vs when it is being displayed to the console. For example, if you have colors enabled and you do
git status
it will colorize the output for different categories of files being listed. However, if you do
git status | less
or
git status > status.txt
it removes the linux color formatting and you only see plain, uncolored text.
How does git
detect whether the output of its commands are going to file vs going to the terminal?
From a shell script, use the
-t
test flag applied to the file descriptor 0 (standard input).Examples:
This is a C Code to demonstrate how to detect if standard output is redirected:
That is how git knows whether the output is going to the terminal or to a file.
isatty(int fd)
will check whether the fd refers to a terminal or something else. It's part ofunistd.h
in the GNU C library.Man page: http://linux.die.net/man/3/isatty
As an aside: if you want to read from a program using another program, but you want to fool
isatty
into thinking that your program is a human, there is a way to do that. You can use a pseudo-terminal (pty). This technique is used by expect, for example.Can confirm that's what git relies on:
Run against the git source tree.
Note that fds 0=stdin, 1=stdout, 2=stderr by default, but these can of course be re-directed or closed (typically if you are a daemon you close your file descriptors and re-open the ones you want).