13

I'm writing command line utility for Linux. If the output (stdout) is going to a shell it would be nice to print some escapes to colorize output. But if the output is being redirected those bash escapes shouldn't be print, or the content might break parsers that rely on that output.

There are several programs that do this (suck as ack) but the ones I found were written in Perl and I couldn't find out how they did it.

I wanted to use C/C++ to write my utility.

Edu Felipe
  • 10,197
  • 13
  • 44
  • 41

3 Answers3

13

You can use isatty on linux. This function is obviously not standard C, since - for example - on many platforms you can't redirect the output to a file.

Andreas Bonini
  • 44,018
  • 30
  • 122
  • 156
9

Have a look at this code:

int is_redirected(){
   if (!isatty(fileno(stdout))){
       fprintf(stdout, "argv, argc, someone is redirecting me elsewhere...\n");
       return 1;
   }
   return 0;
}

/* ... */
int main(int argc, char **argv){
    if (is_redirected()) exit(-1);
    /* ... */
}

That function will return 1 if the program is being redirected. Notice in the main(...) how it is called. If the program was to run and is being redirected to stderr or to a file the program exits immediately.

t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • 1
    probably better to use ``isatty(STDOUT_FILENO)`` instead of using ``fileno()`` – nimrodm Mar 06 '14 at 14:02
  • @nimrodm (or anyone else): why is that? Given the answer to [this question](https://stackoverflow.com/questions/25516375/is-it-possible-that-filenostdout-1-on-a-posix-system), it seems almost better to use `fileno(stdout))`. – 9769953 Apr 27 '23 at 12:26
5

In (non-standard) C, you can use isatty(). In perl, it is done with the -t operator:

$ perl -E 'say -t STDOUT'
1
$ perl -E 'say -t STDOUT' | cat

$

In the shell you can use test:

$ test -t 1 && echo is a tty
is a tty
$ (test -t 1 && echo is a tty ) |  cat
$
William Pursell
  • 204,365
  • 48
  • 270
  • 300