How does a program decide whether or not to have coloured output?Why don't I see escape sequences in...

Why can't we feel the Earth's revolution?

What does the "titan" monster tag mean?

Parallelized for loop in Bash

Can Mage Hand be used to indirectly trigger an attack?

Why is it bad to use your whole foot in rock climbing

In The Incredibles 2, why does Screenslaver's name use a pun on something that doesn't exist in the 1950s pastiche?

Should I move out from my current apartment before the contract ends to save more money?

Is fission/fusion to iron the most efficient way to convert mass to energy?

Is it possible to have battery technology that can't be duplicated?

Why are backslashes included in this shell script?

Someone who is granted access to information but not expected to read it

Can Dive Down protect a creature against Pacifism?

Am I being scammed by a sugar daddy?

Difference between grep -R and -r

Why does there seem to be an extreme lack of public trashcans in Taiwan?

How to search for Android apps without ads?

Certain list transform

My parents claim they cannot pay for my college education; what are my options?

Placement of positioning lights on A320 winglets

I received a gift from my sister who just got back from

What is the color associated with lukewarm?

Why did the Death Eaters wait to reopen the Chamber of Secrets?

How can religions without a hell discourage evil-doing?

How can I find out about the game world without meta-influencing it?



How does a program decide whether or not to have coloured output?


Why don't I see escape sequences in redirected stream OR how is color output implemented?How to trick a command into thinking its output is going to a terminalShell - Customize the color of each line of a log file based on a patternWhy grepping with color doesn't return anything?grep --color=auto breaks when ^M is inside colored matchHow come dc print splits up long numberSSH color show only whiteshow escape sequences in terminal?Converting colored output into htmlHow can one provide colour to tab completion in tcsh?Defining color codes in rxvt-unicodeHow to prevent random console output from breaking the terminal?Is it possible to use ANSI color escape codes in Bash here-documents?Wait for program in a clean way (e.g. in a different terminal window)Why do some programs pass along TTY colours of child programs correctly and others not?Where is the character escape sequence `33[61m` documented to mean bold?Display ANSI colours with curl?How to “echo” colored messages without “-e” option nor intermediate variable?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







17















When I execute a command from a terminal that prints coloured output (such as ls or gcc), the coloured output is printed. From my understanding, the process is actually outputting ANSI escape codes, and the terminal formats the colour.



However, if I execute the same command by another process (say a custom C application) and redirect the output to the application's own output, these colours do not persist.



How does a program decide whether or not to output text with colour format? Is there some environment variable?










share|improve this question































    17















    When I execute a command from a terminal that prints coloured output (such as ls or gcc), the coloured output is printed. From my understanding, the process is actually outputting ANSI escape codes, and the terminal formats the colour.



    However, if I execute the same command by another process (say a custom C application) and redirect the output to the application's own output, these colours do not persist.



    How does a program decide whether or not to output text with colour format? Is there some environment variable?










    share|improve this question



























      17












      17








      17


      1






      When I execute a command from a terminal that prints coloured output (such as ls or gcc), the coloured output is printed. From my understanding, the process is actually outputting ANSI escape codes, and the terminal formats the colour.



      However, if I execute the same command by another process (say a custom C application) and redirect the output to the application's own output, these colours do not persist.



      How does a program decide whether or not to output text with colour format? Is there some environment variable?










      share|improve this question
















      When I execute a command from a terminal that prints coloured output (such as ls or gcc), the coloured output is printed. From my understanding, the process is actually outputting ANSI escape codes, and the terminal formats the colour.



      However, if I execute the same command by another process (say a custom C application) and redirect the output to the application's own output, these colours do not persist.



      How does a program decide whether or not to output text with colour format? Is there some environment variable?







      shell terminal process colors






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 1 hour ago









      muru

      39.5k595171




      39.5k595171










      asked May 18 '16 at 16:32









      Chris SmithChris Smith

      252110




      252110






















          3 Answers
          3






          active

          oldest

          votes


















          26














          Most such programs only output colour codes to a terminal by default; they check to see if their output is a TTY, using isatty(3). There are usually options to override this behaviour: disable colours in all cases, or enable colours in all cases. For GNU grep for example, --color=never disables colours and --color=always enables them.



          In a shell you can perform the same test using the -t test operator: [ -t 1 ] will succeed only if the standard output is a terminal.






          share|improve this answer


























          • Is there some way to trick the started application that the process is a tty?

            – Chris Smith
            May 18 '16 at 16:36






          • 3





            Asked and answered at unix.stackexchange.com/questions/249723 already, chris13523. Comments aren't really the place for follow-on questions, by the way.

            – JdeBP
            May 18 '16 at 16:37






          • 1





            @chris13524 see JdeBP's link; you can also force programs to output colour codes in many cases (see my updated answer).

            – Stephen Kitt
            May 18 '16 at 16:40



















          13















          Is there some environment variable?




          Yes. It is the TERM environment variable. This is because there are several things that are used as part of the decision process.



          It's difficult to generalize here, because not all programs agree on a single decision flowchart. In fact GNU grep, mentioned in M. Kitt's answer, is a good example of an outlier that uses a somewhat unusual decision process with unexpected outcomes. In very general terms, therefore:




          • The standard output must be a terminal device, as determined by isatty().

          • The program must be able to look up the record for the terminal type in the termcap/terminfo database.

          • So therefore there must be a terminal type to look up. The TERM environment variable must exist and its value must match a database record.

          • There must therefore be a terminfo/termcap database. On some implementations of the subsystem, the location of the termcap database can be specified using a TERMCAP environment variable. So on some implementations there is a second environment variable.

          • The termcap/terminfo record must state that the terminal type supports colours. There's a max_colors field in terminfo. It's not set for terminal types that do not actually have colour capabilities. Indeed, there's a terminfo convention that for every colourable terminal type there's another record with -m or -mono appended to the name that states no colour capability.

          • The termcap/terminfo record must provide the way for the program to change colours. There are set_a_foreground and set_a_background fields in terminfo.


          It's a bit more complex than just checking isatty(). It is made further complicated by several things:





          • Some applications add command-line options or configuration flags that override the isatty() check, so that the program always or never assumes that it has a (colourable) terminal as its output. For examples:


            • GNU ls has the --color command-line option.

            • BSD ls looks at the CLICOLOR (its absence meaning never) and CLICOLOR_FORCE (its presence meaning always) environment variables, and also sports the -G command-line option.




          • Some applications don't use termcap/terminfo and have hardwired responses to the value of TERM.

          • Not all terminals use ECMA-48 or ISO 8613-6 SGR sequences, which are slightly mis-named "ANSI escape sequences", for changing colours. The termcap/terminfo mechanism is in fact designed to insulate applications from direct knowledge of the exact control sequences. (Moreover, there's an argument to be had that no-one uses ISO 8613-6 SGR sequences, because everyone agrees on the bug of using semi-colon as the delimiter for RGB colour SGR sequences. The standard actually specifies colon.)


          As mentioned, GNU grep actually exhibits some of these additional complexities. It doesn't consult termcap/terminfo, hardwires the control sequences to emit, and hardwires a response to the TERM environment variable.



          The Linux/Unix port of it has this code, which enables colourization only when the TERM environment variable exists and its value doesn't match the hardwired name dumb:


          int
          should_colorize (void)
          {
          char const *t = getenv ("TERM");
          return t && strcmp (t, "dumb") != 0;
          }


          So even if your TERM is xterm-mono, GNU grep will decide to emit colours, even though other programs such as vim will not.



          The Win32 port of it has this code, which enables colourization either when the TERM environment variable does not exist or when it exists and its value doesn't match the hardwired name dumb:


          int
          should_colorize (void)
          {
          char const *t = getenv ("TERM");
          return ! (t && strcmp (t, "dumb") == 0);
          }


          GNU grep's problems with colour



          GNU grep's colourization is actually notorious. Because it doesn't actually do a proper job of constructing terminal output, but rather just blams in a few hardwired control sequences at various points in its output in the vain hope that that is good enough, it actually displays incorrect output in certain circumstances.



          These circumstances are where it has to colourize something that is at the right hand margin of the terminal. Programs that do terminal output properly have to account for automatic right margins. In addition to the slight possibility that the terminal might not have them (viz the auto_right_margin field in terminfo), the behaviour of terminals that do have automatic right margins often follows the DEC VT precedent of pending line wrap. GNU grep doesn't account for this, naïvely expecting immediate line wrap, and its coloured output goes wrong.



          Coloured output is not a simple thing.



          Further reading




          • Thomas E. Dickey (2016). "grep --color does not show the right output". xterm FAQ. Invisible Island.

          • Jonathan de Boyne Pollard (2016). Italics and colour in manual pages on a nosh user-space virtual terminal. The nosh package.






          share|improve this answer





















          • 2





            As I understand it the OP is asking about the change in behaviour when output is redirected; $TERM doesn't explain that. (Your answer is interesting in general, but I don't think it addresses the question...)

            – Stephen Kitt
            May 18 '16 at 19:35











          • very interesting. I have been wanting an overview like this on how programs discover (or simply "decide") what a terminals capabilities are for a few months now. This also gives an insight why its so hard to find an overview like this - because each program seems to do it slightly differently.

            – the_velour_fog
            May 19 '16 at 9:34



















          0














          The unbuffer command from the expect package de-couples the output from the first program and the input to the second program.



          You would use it like this:



          unbuffer myshellscript.sh | grep value


          I use it all the time with ansible and a homebrewed ctee script so I can see the color output on the terminal, while leaving the log file with normal (non-colorized) output.



          unbuffer ansible-playbook myplaybook.yml | ctee /var/log/ansible/run-$( date "+%F" ).log





          share|improve this answer
























            Your Answer








            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "106"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f283983%2fhow-does-a-program-decide-whether-or-not-to-have-coloured-output%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            26














            Most such programs only output colour codes to a terminal by default; they check to see if their output is a TTY, using isatty(3). There are usually options to override this behaviour: disable colours in all cases, or enable colours in all cases. For GNU grep for example, --color=never disables colours and --color=always enables them.



            In a shell you can perform the same test using the -t test operator: [ -t 1 ] will succeed only if the standard output is a terminal.






            share|improve this answer


























            • Is there some way to trick the started application that the process is a tty?

              – Chris Smith
              May 18 '16 at 16:36






            • 3





              Asked and answered at unix.stackexchange.com/questions/249723 already, chris13523. Comments aren't really the place for follow-on questions, by the way.

              – JdeBP
              May 18 '16 at 16:37






            • 1





              @chris13524 see JdeBP's link; you can also force programs to output colour codes in many cases (see my updated answer).

              – Stephen Kitt
              May 18 '16 at 16:40
















            26














            Most such programs only output colour codes to a terminal by default; they check to see if their output is a TTY, using isatty(3). There are usually options to override this behaviour: disable colours in all cases, or enable colours in all cases. For GNU grep for example, --color=never disables colours and --color=always enables them.



            In a shell you can perform the same test using the -t test operator: [ -t 1 ] will succeed only if the standard output is a terminal.






            share|improve this answer


























            • Is there some way to trick the started application that the process is a tty?

              – Chris Smith
              May 18 '16 at 16:36






            • 3





              Asked and answered at unix.stackexchange.com/questions/249723 already, chris13523. Comments aren't really the place for follow-on questions, by the way.

              – JdeBP
              May 18 '16 at 16:37






            • 1





              @chris13524 see JdeBP's link; you can also force programs to output colour codes in many cases (see my updated answer).

              – Stephen Kitt
              May 18 '16 at 16:40














            26












            26








            26







            Most such programs only output colour codes to a terminal by default; they check to see if their output is a TTY, using isatty(3). There are usually options to override this behaviour: disable colours in all cases, or enable colours in all cases. For GNU grep for example, --color=never disables colours and --color=always enables them.



            In a shell you can perform the same test using the -t test operator: [ -t 1 ] will succeed only if the standard output is a terminal.






            share|improve this answer















            Most such programs only output colour codes to a terminal by default; they check to see if their output is a TTY, using isatty(3). There are usually options to override this behaviour: disable colours in all cases, or enable colours in all cases. For GNU grep for example, --color=never disables colours and --color=always enables them.



            In a shell you can perform the same test using the -t test operator: [ -t 1 ] will succeed only if the standard output is a terminal.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited May 18 '16 at 16:37

























            answered May 18 '16 at 16:35









            Stephen KittStephen Kitt

            190k26446522




            190k26446522













            • Is there some way to trick the started application that the process is a tty?

              – Chris Smith
              May 18 '16 at 16:36






            • 3





              Asked and answered at unix.stackexchange.com/questions/249723 already, chris13523. Comments aren't really the place for follow-on questions, by the way.

              – JdeBP
              May 18 '16 at 16:37






            • 1





              @chris13524 see JdeBP's link; you can also force programs to output colour codes in many cases (see my updated answer).

              – Stephen Kitt
              May 18 '16 at 16:40



















            • Is there some way to trick the started application that the process is a tty?

              – Chris Smith
              May 18 '16 at 16:36






            • 3





              Asked and answered at unix.stackexchange.com/questions/249723 already, chris13523. Comments aren't really the place for follow-on questions, by the way.

              – JdeBP
              May 18 '16 at 16:37






            • 1





              @chris13524 see JdeBP's link; you can also force programs to output colour codes in many cases (see my updated answer).

              – Stephen Kitt
              May 18 '16 at 16:40

















            Is there some way to trick the started application that the process is a tty?

            – Chris Smith
            May 18 '16 at 16:36





            Is there some way to trick the started application that the process is a tty?

            – Chris Smith
            May 18 '16 at 16:36




            3




            3





            Asked and answered at unix.stackexchange.com/questions/249723 already, chris13523. Comments aren't really the place for follow-on questions, by the way.

            – JdeBP
            May 18 '16 at 16:37





            Asked and answered at unix.stackexchange.com/questions/249723 already, chris13523. Comments aren't really the place for follow-on questions, by the way.

            – JdeBP
            May 18 '16 at 16:37




            1




            1





            @chris13524 see JdeBP's link; you can also force programs to output colour codes in many cases (see my updated answer).

            – Stephen Kitt
            May 18 '16 at 16:40





            @chris13524 see JdeBP's link; you can also force programs to output colour codes in many cases (see my updated answer).

            – Stephen Kitt
            May 18 '16 at 16:40













            13















            Is there some environment variable?




            Yes. It is the TERM environment variable. This is because there are several things that are used as part of the decision process.



            It's difficult to generalize here, because not all programs agree on a single decision flowchart. In fact GNU grep, mentioned in M. Kitt's answer, is a good example of an outlier that uses a somewhat unusual decision process with unexpected outcomes. In very general terms, therefore:




            • The standard output must be a terminal device, as determined by isatty().

            • The program must be able to look up the record for the terminal type in the termcap/terminfo database.

            • So therefore there must be a terminal type to look up. The TERM environment variable must exist and its value must match a database record.

            • There must therefore be a terminfo/termcap database. On some implementations of the subsystem, the location of the termcap database can be specified using a TERMCAP environment variable. So on some implementations there is a second environment variable.

            • The termcap/terminfo record must state that the terminal type supports colours. There's a max_colors field in terminfo. It's not set for terminal types that do not actually have colour capabilities. Indeed, there's a terminfo convention that for every colourable terminal type there's another record with -m or -mono appended to the name that states no colour capability.

            • The termcap/terminfo record must provide the way for the program to change colours. There are set_a_foreground and set_a_background fields in terminfo.


            It's a bit more complex than just checking isatty(). It is made further complicated by several things:





            • Some applications add command-line options or configuration flags that override the isatty() check, so that the program always or never assumes that it has a (colourable) terminal as its output. For examples:


              • GNU ls has the --color command-line option.

              • BSD ls looks at the CLICOLOR (its absence meaning never) and CLICOLOR_FORCE (its presence meaning always) environment variables, and also sports the -G command-line option.




            • Some applications don't use termcap/terminfo and have hardwired responses to the value of TERM.

            • Not all terminals use ECMA-48 or ISO 8613-6 SGR sequences, which are slightly mis-named "ANSI escape sequences", for changing colours. The termcap/terminfo mechanism is in fact designed to insulate applications from direct knowledge of the exact control sequences. (Moreover, there's an argument to be had that no-one uses ISO 8613-6 SGR sequences, because everyone agrees on the bug of using semi-colon as the delimiter for RGB colour SGR sequences. The standard actually specifies colon.)


            As mentioned, GNU grep actually exhibits some of these additional complexities. It doesn't consult termcap/terminfo, hardwires the control sequences to emit, and hardwires a response to the TERM environment variable.



            The Linux/Unix port of it has this code, which enables colourization only when the TERM environment variable exists and its value doesn't match the hardwired name dumb:


            int
            should_colorize (void)
            {
            char const *t = getenv ("TERM");
            return t && strcmp (t, "dumb") != 0;
            }


            So even if your TERM is xterm-mono, GNU grep will decide to emit colours, even though other programs such as vim will not.



            The Win32 port of it has this code, which enables colourization either when the TERM environment variable does not exist or when it exists and its value doesn't match the hardwired name dumb:


            int
            should_colorize (void)
            {
            char const *t = getenv ("TERM");
            return ! (t && strcmp (t, "dumb") == 0);
            }


            GNU grep's problems with colour



            GNU grep's colourization is actually notorious. Because it doesn't actually do a proper job of constructing terminal output, but rather just blams in a few hardwired control sequences at various points in its output in the vain hope that that is good enough, it actually displays incorrect output in certain circumstances.



            These circumstances are where it has to colourize something that is at the right hand margin of the terminal. Programs that do terminal output properly have to account for automatic right margins. In addition to the slight possibility that the terminal might not have them (viz the auto_right_margin field in terminfo), the behaviour of terminals that do have automatic right margins often follows the DEC VT precedent of pending line wrap. GNU grep doesn't account for this, naïvely expecting immediate line wrap, and its coloured output goes wrong.



            Coloured output is not a simple thing.



            Further reading




            • Thomas E. Dickey (2016). "grep --color does not show the right output". xterm FAQ. Invisible Island.

            • Jonathan de Boyne Pollard (2016). Italics and colour in manual pages on a nosh user-space virtual terminal. The nosh package.






            share|improve this answer





















            • 2





              As I understand it the OP is asking about the change in behaviour when output is redirected; $TERM doesn't explain that. (Your answer is interesting in general, but I don't think it addresses the question...)

              – Stephen Kitt
              May 18 '16 at 19:35











            • very interesting. I have been wanting an overview like this on how programs discover (or simply "decide") what a terminals capabilities are for a few months now. This also gives an insight why its so hard to find an overview like this - because each program seems to do it slightly differently.

              – the_velour_fog
              May 19 '16 at 9:34
















            13















            Is there some environment variable?




            Yes. It is the TERM environment variable. This is because there are several things that are used as part of the decision process.



            It's difficult to generalize here, because not all programs agree on a single decision flowchart. In fact GNU grep, mentioned in M. Kitt's answer, is a good example of an outlier that uses a somewhat unusual decision process with unexpected outcomes. In very general terms, therefore:




            • The standard output must be a terminal device, as determined by isatty().

            • The program must be able to look up the record for the terminal type in the termcap/terminfo database.

            • So therefore there must be a terminal type to look up. The TERM environment variable must exist and its value must match a database record.

            • There must therefore be a terminfo/termcap database. On some implementations of the subsystem, the location of the termcap database can be specified using a TERMCAP environment variable. So on some implementations there is a second environment variable.

            • The termcap/terminfo record must state that the terminal type supports colours. There's a max_colors field in terminfo. It's not set for terminal types that do not actually have colour capabilities. Indeed, there's a terminfo convention that for every colourable terminal type there's another record with -m or -mono appended to the name that states no colour capability.

            • The termcap/terminfo record must provide the way for the program to change colours. There are set_a_foreground and set_a_background fields in terminfo.


            It's a bit more complex than just checking isatty(). It is made further complicated by several things:





            • Some applications add command-line options or configuration flags that override the isatty() check, so that the program always or never assumes that it has a (colourable) terminal as its output. For examples:


              • GNU ls has the --color command-line option.

              • BSD ls looks at the CLICOLOR (its absence meaning never) and CLICOLOR_FORCE (its presence meaning always) environment variables, and also sports the -G command-line option.




            • Some applications don't use termcap/terminfo and have hardwired responses to the value of TERM.

            • Not all terminals use ECMA-48 or ISO 8613-6 SGR sequences, which are slightly mis-named "ANSI escape sequences", for changing colours. The termcap/terminfo mechanism is in fact designed to insulate applications from direct knowledge of the exact control sequences. (Moreover, there's an argument to be had that no-one uses ISO 8613-6 SGR sequences, because everyone agrees on the bug of using semi-colon as the delimiter for RGB colour SGR sequences. The standard actually specifies colon.)


            As mentioned, GNU grep actually exhibits some of these additional complexities. It doesn't consult termcap/terminfo, hardwires the control sequences to emit, and hardwires a response to the TERM environment variable.



            The Linux/Unix port of it has this code, which enables colourization only when the TERM environment variable exists and its value doesn't match the hardwired name dumb:


            int
            should_colorize (void)
            {
            char const *t = getenv ("TERM");
            return t && strcmp (t, "dumb") != 0;
            }


            So even if your TERM is xterm-mono, GNU grep will decide to emit colours, even though other programs such as vim will not.



            The Win32 port of it has this code, which enables colourization either when the TERM environment variable does not exist or when it exists and its value doesn't match the hardwired name dumb:


            int
            should_colorize (void)
            {
            char const *t = getenv ("TERM");
            return ! (t && strcmp (t, "dumb") == 0);
            }


            GNU grep's problems with colour



            GNU grep's colourization is actually notorious. Because it doesn't actually do a proper job of constructing terminal output, but rather just blams in a few hardwired control sequences at various points in its output in the vain hope that that is good enough, it actually displays incorrect output in certain circumstances.



            These circumstances are where it has to colourize something that is at the right hand margin of the terminal. Programs that do terminal output properly have to account for automatic right margins. In addition to the slight possibility that the terminal might not have them (viz the auto_right_margin field in terminfo), the behaviour of terminals that do have automatic right margins often follows the DEC VT precedent of pending line wrap. GNU grep doesn't account for this, naïvely expecting immediate line wrap, and its coloured output goes wrong.



            Coloured output is not a simple thing.



            Further reading




            • Thomas E. Dickey (2016). "grep --color does not show the right output". xterm FAQ. Invisible Island.

            • Jonathan de Boyne Pollard (2016). Italics and colour in manual pages on a nosh user-space virtual terminal. The nosh package.






            share|improve this answer





















            • 2





              As I understand it the OP is asking about the change in behaviour when output is redirected; $TERM doesn't explain that. (Your answer is interesting in general, but I don't think it addresses the question...)

              – Stephen Kitt
              May 18 '16 at 19:35











            • very interesting. I have been wanting an overview like this on how programs discover (or simply "decide") what a terminals capabilities are for a few months now. This also gives an insight why its so hard to find an overview like this - because each program seems to do it slightly differently.

              – the_velour_fog
              May 19 '16 at 9:34














            13












            13








            13








            Is there some environment variable?




            Yes. It is the TERM environment variable. This is because there are several things that are used as part of the decision process.



            It's difficult to generalize here, because not all programs agree on a single decision flowchart. In fact GNU grep, mentioned in M. Kitt's answer, is a good example of an outlier that uses a somewhat unusual decision process with unexpected outcomes. In very general terms, therefore:




            • The standard output must be a terminal device, as determined by isatty().

            • The program must be able to look up the record for the terminal type in the termcap/terminfo database.

            • So therefore there must be a terminal type to look up. The TERM environment variable must exist and its value must match a database record.

            • There must therefore be a terminfo/termcap database. On some implementations of the subsystem, the location of the termcap database can be specified using a TERMCAP environment variable. So on some implementations there is a second environment variable.

            • The termcap/terminfo record must state that the terminal type supports colours. There's a max_colors field in terminfo. It's not set for terminal types that do not actually have colour capabilities. Indeed, there's a terminfo convention that for every colourable terminal type there's another record with -m or -mono appended to the name that states no colour capability.

            • The termcap/terminfo record must provide the way for the program to change colours. There are set_a_foreground and set_a_background fields in terminfo.


            It's a bit more complex than just checking isatty(). It is made further complicated by several things:





            • Some applications add command-line options or configuration flags that override the isatty() check, so that the program always or never assumes that it has a (colourable) terminal as its output. For examples:


              • GNU ls has the --color command-line option.

              • BSD ls looks at the CLICOLOR (its absence meaning never) and CLICOLOR_FORCE (its presence meaning always) environment variables, and also sports the -G command-line option.




            • Some applications don't use termcap/terminfo and have hardwired responses to the value of TERM.

            • Not all terminals use ECMA-48 or ISO 8613-6 SGR sequences, which are slightly mis-named "ANSI escape sequences", for changing colours. The termcap/terminfo mechanism is in fact designed to insulate applications from direct knowledge of the exact control sequences. (Moreover, there's an argument to be had that no-one uses ISO 8613-6 SGR sequences, because everyone agrees on the bug of using semi-colon as the delimiter for RGB colour SGR sequences. The standard actually specifies colon.)


            As mentioned, GNU grep actually exhibits some of these additional complexities. It doesn't consult termcap/terminfo, hardwires the control sequences to emit, and hardwires a response to the TERM environment variable.



            The Linux/Unix port of it has this code, which enables colourization only when the TERM environment variable exists and its value doesn't match the hardwired name dumb:


            int
            should_colorize (void)
            {
            char const *t = getenv ("TERM");
            return t && strcmp (t, "dumb") != 0;
            }


            So even if your TERM is xterm-mono, GNU grep will decide to emit colours, even though other programs such as vim will not.



            The Win32 port of it has this code, which enables colourization either when the TERM environment variable does not exist or when it exists and its value doesn't match the hardwired name dumb:


            int
            should_colorize (void)
            {
            char const *t = getenv ("TERM");
            return ! (t && strcmp (t, "dumb") == 0);
            }


            GNU grep's problems with colour



            GNU grep's colourization is actually notorious. Because it doesn't actually do a proper job of constructing terminal output, but rather just blams in a few hardwired control sequences at various points in its output in the vain hope that that is good enough, it actually displays incorrect output in certain circumstances.



            These circumstances are where it has to colourize something that is at the right hand margin of the terminal. Programs that do terminal output properly have to account for automatic right margins. In addition to the slight possibility that the terminal might not have them (viz the auto_right_margin field in terminfo), the behaviour of terminals that do have automatic right margins often follows the DEC VT precedent of pending line wrap. GNU grep doesn't account for this, naïvely expecting immediate line wrap, and its coloured output goes wrong.



            Coloured output is not a simple thing.



            Further reading




            • Thomas E. Dickey (2016). "grep --color does not show the right output". xterm FAQ. Invisible Island.

            • Jonathan de Boyne Pollard (2016). Italics and colour in manual pages on a nosh user-space virtual terminal. The nosh package.






            share|improve this answer
















            Is there some environment variable?




            Yes. It is the TERM environment variable. This is because there are several things that are used as part of the decision process.



            It's difficult to generalize here, because not all programs agree on a single decision flowchart. In fact GNU grep, mentioned in M. Kitt's answer, is a good example of an outlier that uses a somewhat unusual decision process with unexpected outcomes. In very general terms, therefore:




            • The standard output must be a terminal device, as determined by isatty().

            • The program must be able to look up the record for the terminal type in the termcap/terminfo database.

            • So therefore there must be a terminal type to look up. The TERM environment variable must exist and its value must match a database record.

            • There must therefore be a terminfo/termcap database. On some implementations of the subsystem, the location of the termcap database can be specified using a TERMCAP environment variable. So on some implementations there is a second environment variable.

            • The termcap/terminfo record must state that the terminal type supports colours. There's a max_colors field in terminfo. It's not set for terminal types that do not actually have colour capabilities. Indeed, there's a terminfo convention that for every colourable terminal type there's another record with -m or -mono appended to the name that states no colour capability.

            • The termcap/terminfo record must provide the way for the program to change colours. There are set_a_foreground and set_a_background fields in terminfo.


            It's a bit more complex than just checking isatty(). It is made further complicated by several things:





            • Some applications add command-line options or configuration flags that override the isatty() check, so that the program always or never assumes that it has a (colourable) terminal as its output. For examples:


              • GNU ls has the --color command-line option.

              • BSD ls looks at the CLICOLOR (its absence meaning never) and CLICOLOR_FORCE (its presence meaning always) environment variables, and also sports the -G command-line option.




            • Some applications don't use termcap/terminfo and have hardwired responses to the value of TERM.

            • Not all terminals use ECMA-48 or ISO 8613-6 SGR sequences, which are slightly mis-named "ANSI escape sequences", for changing colours. The termcap/terminfo mechanism is in fact designed to insulate applications from direct knowledge of the exact control sequences. (Moreover, there's an argument to be had that no-one uses ISO 8613-6 SGR sequences, because everyone agrees on the bug of using semi-colon as the delimiter for RGB colour SGR sequences. The standard actually specifies colon.)


            As mentioned, GNU grep actually exhibits some of these additional complexities. It doesn't consult termcap/terminfo, hardwires the control sequences to emit, and hardwires a response to the TERM environment variable.



            The Linux/Unix port of it has this code, which enables colourization only when the TERM environment variable exists and its value doesn't match the hardwired name dumb:


            int
            should_colorize (void)
            {
            char const *t = getenv ("TERM");
            return t && strcmp (t, "dumb") != 0;
            }


            So even if your TERM is xterm-mono, GNU grep will decide to emit colours, even though other programs such as vim will not.



            The Win32 port of it has this code, which enables colourization either when the TERM environment variable does not exist or when it exists and its value doesn't match the hardwired name dumb:


            int
            should_colorize (void)
            {
            char const *t = getenv ("TERM");
            return ! (t && strcmp (t, "dumb") == 0);
            }


            GNU grep's problems with colour



            GNU grep's colourization is actually notorious. Because it doesn't actually do a proper job of constructing terminal output, but rather just blams in a few hardwired control sequences at various points in its output in the vain hope that that is good enough, it actually displays incorrect output in certain circumstances.



            These circumstances are where it has to colourize something that is at the right hand margin of the terminal. Programs that do terminal output properly have to account for automatic right margins. In addition to the slight possibility that the terminal might not have them (viz the auto_right_margin field in terminfo), the behaviour of terminals that do have automatic right margins often follows the DEC VT precedent of pending line wrap. GNU grep doesn't account for this, naïvely expecting immediate line wrap, and its coloured output goes wrong.



            Coloured output is not a simple thing.



            Further reading




            • Thomas E. Dickey (2016). "grep --color does not show the right output". xterm FAQ. Invisible Island.

            • Jonathan de Boyne Pollard (2016). Italics and colour in manual pages on a nosh user-space virtual terminal. The nosh package.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Oct 27 '16 at 7:41

























            answered May 18 '16 at 18:27









            JdeBPJdeBP

            40.1k484196




            40.1k484196








            • 2





              As I understand it the OP is asking about the change in behaviour when output is redirected; $TERM doesn't explain that. (Your answer is interesting in general, but I don't think it addresses the question...)

              – Stephen Kitt
              May 18 '16 at 19:35











            • very interesting. I have been wanting an overview like this on how programs discover (or simply "decide") what a terminals capabilities are for a few months now. This also gives an insight why its so hard to find an overview like this - because each program seems to do it slightly differently.

              – the_velour_fog
              May 19 '16 at 9:34














            • 2





              As I understand it the OP is asking about the change in behaviour when output is redirected; $TERM doesn't explain that. (Your answer is interesting in general, but I don't think it addresses the question...)

              – Stephen Kitt
              May 18 '16 at 19:35











            • very interesting. I have been wanting an overview like this on how programs discover (or simply "decide") what a terminals capabilities are for a few months now. This also gives an insight why its so hard to find an overview like this - because each program seems to do it slightly differently.

              – the_velour_fog
              May 19 '16 at 9:34








            2




            2





            As I understand it the OP is asking about the change in behaviour when output is redirected; $TERM doesn't explain that. (Your answer is interesting in general, but I don't think it addresses the question...)

            – Stephen Kitt
            May 18 '16 at 19:35





            As I understand it the OP is asking about the change in behaviour when output is redirected; $TERM doesn't explain that. (Your answer is interesting in general, but I don't think it addresses the question...)

            – Stephen Kitt
            May 18 '16 at 19:35













            very interesting. I have been wanting an overview like this on how programs discover (or simply "decide") what a terminals capabilities are for a few months now. This also gives an insight why its so hard to find an overview like this - because each program seems to do it slightly differently.

            – the_velour_fog
            May 19 '16 at 9:34





            very interesting. I have been wanting an overview like this on how programs discover (or simply "decide") what a terminals capabilities are for a few months now. This also gives an insight why its so hard to find an overview like this - because each program seems to do it slightly differently.

            – the_velour_fog
            May 19 '16 at 9:34











            0














            The unbuffer command from the expect package de-couples the output from the first program and the input to the second program.



            You would use it like this:



            unbuffer myshellscript.sh | grep value


            I use it all the time with ansible and a homebrewed ctee script so I can see the color output on the terminal, while leaving the log file with normal (non-colorized) output.



            unbuffer ansible-playbook myplaybook.yml | ctee /var/log/ansible/run-$( date "+%F" ).log





            share|improve this answer




























              0














              The unbuffer command from the expect package de-couples the output from the first program and the input to the second program.



              You would use it like this:



              unbuffer myshellscript.sh | grep value


              I use it all the time with ansible and a homebrewed ctee script so I can see the color output on the terminal, while leaving the log file with normal (non-colorized) output.



              unbuffer ansible-playbook myplaybook.yml | ctee /var/log/ansible/run-$( date "+%F" ).log





              share|improve this answer


























                0












                0








                0







                The unbuffer command from the expect package de-couples the output from the first program and the input to the second program.



                You would use it like this:



                unbuffer myshellscript.sh | grep value


                I use it all the time with ansible and a homebrewed ctee script so I can see the color output on the terminal, while leaving the log file with normal (non-colorized) output.



                unbuffer ansible-playbook myplaybook.yml | ctee /var/log/ansible/run-$( date "+%F" ).log





                share|improve this answer













                The unbuffer command from the expect package de-couples the output from the first program and the input to the second program.



                You would use it like this:



                unbuffer myshellscript.sh | grep value


                I use it all the time with ansible and a homebrewed ctee script so I can see the color output on the terminal, while leaving the log file with normal (non-colorized) output.



                unbuffer ansible-playbook myplaybook.yml | ctee /var/log/ansible/run-$( date "+%F" ).log






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 14 '18 at 21:06









                bgStack15bgStack15

                1919




                1919






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Unix & Linux Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f283983%2fhow-does-a-program-decide-whether-or-not-to-have-coloured-output%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

                    Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

                    Nicolae Petrescu-Găină Cuprins Biografie | Opera | In memoriam | Varia | Controverse, incertitudini...