Many Linux programs with a command line interface use different escape sequences to color the text. For example, you can color text red by displaying the sequence 0x1B[31m
in front of it. When I do this in my programs, if I redirect the program output to a file, it will contain these sequences. However, if, for example, I redirect the output of the git status
command to a file, it will contain only text -- no escape sequences.
For example, here is my Pascal program:
program ColorPrinting;
begin
writeln(#27'[31m', 'Hello, world!', #27'[0m')
end.
If its output is redirected to a file, it will contain escape sequences, which is to be expected:
$ ./test | hexdump -C
00000000 1b 5b 33 31 6d 48 65 6c 6c 6f 2c 20 77 6f 72 6c |.[31mHello, worl|
00000010 64 21 1b 5b 30 6d 0a |d!.[0m.|
00000017
However, if I do the same for the Git program (which turns staged changes green and unstaged changes red), its output is plain text:
$ git status -s > git-status.out && hexdump -C git-status.out
00000000 41 20 20 2e 67 69 74 69 67 6e 6f 72 65 0a 3f 3f |A .gitignore.??|
00000010 20 67 69 74 2d 73 74 61 74 75 73 2e 6f 75 74 0a | git-status.out.|
00000020 3f 3f 20 74 65 73 74 2e 6f 75 74 0a 3f 3f 20 74 |?? test.out.?? t|
00000030 65 73 74 2e 70 61 73 0a |est.pas.|
00000038
If I understand correctly, programs don't know what happens to their output at all -- the Bash shell does the redirection itself. Then how does it work? Does Bash automatically clean some programs' output stream from escape sequences? Or is it something else?