Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no colors on stderr when redirecting stdout #125

Open
andbleo opened this issue Dec 24, 2022 · 8 comments
Open

no colors on stderr when redirecting stdout #125

andbleo opened this issue Dec 24, 2022 · 8 comments

Comments

@andbleo
Copy link

andbleo commented Dec 24, 2022

If I want color output on stderr or stdout, I get colors. If I have colored stdout and redirect stderr to /dev/null, I still get color on stdout. If I have colored stderr and redirect stdout to /dev/null, I no longer get color on stderr. Is this expected behavior?

I ran into this issue when using simple_logger 4.0.0, but the problem appears to lie with colored (see here: https://docs.rs/colored/latest/src/colored/control.rs.html#108). The version of colored used was 2.0.0 and this was seen on macOS.
Here is the original ticket I made in simple_logger: borntyping/rust-simple_logger#71

@hwittenborn
Copy link
Member

hwittenborn commented Jul 1, 2023

I'm pretty sure this is due to

&& atty::is(atty::Stream::Stdout),
, which only checks if stdout is a TTY. When you redirect it to /dev/null, I'm assuming stdout is no longer a TTY, and then colorizing gets disabled.

I don't think that should be intended behavior - I think a better solution would be to check if both stdout and stderr are not TTYs, and only then do the automatic color disabling.

Is the TTY stuff a documented feature though @mackwic? I'm not quite sure on what would be good behavior for it, and I think removing it might just be better honestly. Do you have any ideas on what the best approach might be though?

@mackwic
Copy link
Collaborator

mackwic commented Jul 2, 2023

Disable coloring when the stdout is not a TTY is a standard practice in many unix tooling. For example ls | cat does not colorize by default unless you force it with the --color flag.

The rules for colorization are quite obscure, badly documented, and the threshold varies depending on who you're talking to. I think that the state of the art is to detect if your stdout is a tty and then check the TERM environment variable for color capabilities, but it's not so clear what are the correct values to colorize. For example, someone told me that xterm should not get any color while xterm-256 take them all. It seems bizarre to me, the term should skip over escape values it doesn't support. It's not written anywhere I could find so, until someone explain clearly what the rules are, colored does not check TERM. (related issue: #108, PR: #128)

Anyway, current behavior is what's intended at time of writing the software.
More control can be obtained through the control environment variables, which is what user should use when they really want to get a specific behavior, as we can't really guess all the use cases.

@hwittenborn
Copy link
Member

Disable coloring when the stdout is not a TTY is a standard practice in many unix tooling.

I did some testing and the same behavior applies to dpkg and apt, both of which also disable coloring on stderr if stdout is piped. Based off of that I think it'd be good to keep the current behavior as well.

@hwittenborn
Copy link
Member

I'll do some looking into the rules for the TERM variable as well, I'll try to find anything concrete on what values support what. If any of y'all know of any resources definitely feel free to send them.

@AsPulse
Copy link

AsPulse commented Aug 24, 2023

Some programs which use stdout for another purpose, sometimes use stderr as output to the user.
cargo is one of them, but in cases like it, I would like to have output to stderr with color, even if stdout is redirected.

I think the concerns mentioned before are also true,

I would be very happy if the option that enables stderr to output with color was implemented.
A closer look at the source code showed that it already existed. I apologize for not checking carefully. I'll leave it here for anyone else who has had trouble with the same thing:

use colored;
colored::control::set_override(true);

(cargo outputs pre-execution messages to stderr with color even if stdout is redirected)
image

I am learning English, so please overlook any grammatical errors;;

@mackwic
Copy link
Collaborator

mackwic commented Aug 25, 2023 via email

@mackwic
Copy link
Collaborator

mackwic commented Aug 25, 2023 via email

@spoutn1k
Copy link

spoutn1k commented Apr 30, 2024

Hey all I just came from a logging library that has this exact issue inherited directly from colored.

I just want to highlight the fact that ls, apt, dpkg are front-ends that make this design choice, but that as far as I am seeing this is a library crate only and should not make such opinionated, undocumented choices.

Maybe a initialization flag could used to set the crate behaviour, akin to:

enum ColorMode {
    Never,
    Always,
    AutoStdout, // The current default
    AutoStderr,
}

I will make a PR implementing the above (with the default behaviour as the current behaviour) if there are no objections.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants