What effect does auto as an option for the --color switch have in grep? When does grep decide to color the the matching strings, and when doesn't it?
1 Answers
Expected behavior
With --color=auto, grep will highlight matching strings if (and only if) the output is written directly to the terminal and said terminal is capable of displaying colored output.
Normally, --color=auto is what you want. If, e.g., you use grep to match a URL and pipe it to Wget, Wget will see \e[1;31mhttp://... instead of the actual URL (and choke on it).
The following commands should result in colored output:
echo Super User | grep --color=auto Super
echo Super User | grep --color=always Super | cat
This command, however, should not:
echo Super User | grep --color=auto Super | cat
Any inconsistency with this behavior should be considered a bug.
Source code
With --color=auto, the latest Grep for Windows version (2.5.4) – as well as the original 2.5.4 it is based on – color the output if and only if the condition
isatty(STDOUT_FILENO) && getenv("TERM") && strcmp(getenv("TERM"), "dumb")
is true, i.e., if and only if the output is being written to a terminal, the environment variable TERM is defined and the terminal is not dumb.
This won't produce the desired behavior under Windows, since TERM is normally not defined. An easy solution to this problem is setting the TERM=windows in the control panel.
The latest version of grep (2.14) fixes this issue by coloring the output if and only if the condition
isatty(STDOUT_FILENO) && should_colorize()
is true, where should_colorize() is defined differently for POSIX and Win32:
For the former, the condition is equivalent to the one of 2.5.4; for the latter, the enviroment variable TERM doesn't have to be set (it just can't be dumb).
-
How does it find out if it writes to the terminal or not? – trolzen Nov 02 '12 at 11:29
-
1There's a C function for that. If you include the header file `sdgstd.h`, `istty(stdout)` returns `0` if the output is redirected to a file. – Dennis Nov 02 '12 at 11:53
-
I experiment with windows ports of `grep` and `less` from GnuWin project (gnuwin32.sourceforge.net). `cmd.exe` is improved with `ansicon` utility. `less --color=auto` works as expected: uses color when no redirection is applied and does not when output is redirected. But `grep --color=auto` doesn't print escape sequences in both cases. – trolzen Nov 02 '12 at 15:13
-
I cannot understand why this happens. I thought these utilities have the same code both in unix and windows versions and they are quite old. So they should behave identically. – trolzen Nov 02 '12 at 15:19
-
That's a bug in GnuWin32's grep then. On Ubuntu, it behaves as I detailed in my answer. While both derive from the same source code, there are always minor adjustments that have to be made if you're going to compile on another platform. Also, keep in mind that GnuWin32's current version of grep is 2.5.4. The latest version on Ubuntu is 2.12. – Dennis Nov 02 '12 at 15:34
-
I've dowloaded sources for grep-2.14, coreutils-8.20, diffutils-3.2, gawk-4.0.1 from http://ftp.gnu.org/gnu/ and haven't found neither `sdgstd` nor `istty` (there are few occurences of `istty` in gawk, but those are not function call but variable names) – trolzen Nov 02 '12 at 16:08
-
On Windows, you should be able to use `_isatty(_fileno(stdout))`. You need to include either `io.h` or `unistd.h`. – Dennis Nov 02 '12 at 16:12
-
I think I wasn't clear. I've dowloaded sources for _linux_ versions. And in that _linux_ sources there are no strings like "isatty". – trolzen Nov 02 '12 at 17:27
-
Ah, I thought you wanted to fix the Windows version... It doesn't *have to* be `isatty`; that was just an example. `isatty(fileno(stdout))` would also work, and there are probably a few other ways. – Dennis Nov 02 '12 at 22:03
-
Actually yes, I'd like to fix the windows version. So I want to understand why is there a difference between versions and how do programs determine whether they write to terminal or not. Are there any other functions besides `istty()` and `_isatty()`? – trolzen Nov 03 '12 at 10:58
-
It's in `main.c`, line `2185`: `if (color_option == 2) color_option = isatty (STDOUT_FILENO) && should_colorize ();` – Dennis Nov 03 '12 at 19:56
-
I finally figured out. `grep` not only calls `isatty()`, it check for environment variable `TERM` (unlike `ls`). If it is undefined (under windows it is usually) then `grep` doesn't use colors. Under linux there are also some situations when `TERM` is undefined. – trolzen Nov 08 '12 at 03:54
-
Edited the answer. Couple of notes: 1) there is no function `istty`, maybe misprint and 2) I don't know why I wrote `less` above, I meant `ls` :-). @dennis thanks for the help! – trolzen Nov 08 '12 at 04:48
-
could you please add this change to the answer? http://superuser.com/review/suggested-edits/50586 – trolzen Nov 11 '12 at 08:07
-
I've edited my answer to incorporate the information you mentioned. The `istty` function does exist, but it's part of [Thinkage GCOS](http://www.thinkage.ca/english/gcos/index.shtml), not the standard libraries. – Dennis Nov 13 '12 at 14:51