Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Disabling ANSI color output (no-color.org)
39 points by colinprince on Feb 7, 2018 | hide | past | favorite | 52 comments


The comments on the homebrew merge request are incredibly frustrating to me, as the kind of insanity that can lead someone to think there are only four programs that offer an ability to disable colours is something I thought I escaped by avoiding Facebook.

Here's the workaround I use:

    brew() { /usr/local/bin/brew "$@" | cat; }


The rejection is not about the ability to disable colours but about adopting a "standard" that someone made up by themselves.


> The rejection is not about the ability to disable colours

That's all the code does.

> … but about adopting a "standard" that someone made up by themselves.

People's imagination is where standards come from.

People make them up and get agreement from other people to implement them.


On one level the code allows disabling color with a flag. On another level, the code provides support for a nascent attempt at creating a new standard.

Software development is a social activity, and if someone wants to introduce new functionality, they have to convince others that it's a desirable change. Making up a "standard" is the easy part; I'd expect that convincing others to adopt it is more challenging.


Color/styled text is a weird case, since it tends to be used for improving output (e.g. highlighting a “diff” or code syntax). It can be annoying to have all that helpful highlighting go away just because you added something like a pipe to “less” in your command to keep your text from scrolling away. The real problem is how a program is supposed to know when your pipe is meant to be interactive.

Technically terminals can play the interactive role in place of “less”: ^S/^Q, scrollback and search, etc. If that were more common, programs might not be misusing color/style sequences like this (as there wouldn’t be a common “interactive pipe” use case to support).


Use 'less -r' to display ANSI color in less.


Crazy idea - what if other utilites were aware of ANSI codes and behaved appropriately? For example 'grep' could ignore color sequences when doing pattern-matching, and then re-apply the colors to the output. Then you could do something like `git log | grep` and see the original coloration in the output.


> Crazy idea - what if other utilites were aware of ANSI codes and behaved appropriately?

If ANSI sequences were only color, they might be feasible; getting a clear idea on what “appropriately” means for general ANSI content in a text stream is... difficult.


I'd be happy with just the Graphic parameters https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_G...


I wonder if tmux or iTerm2 could have an option to not autoscroll the command off the screen.


At least most software has the decency of checking that stdout is a terminal before colorizing output, so I just pipe to cat. I suppose this is a borderline case[0].

[0] https://en.wikipedia.org/wiki/Cat_(Unix)#UUOC_(Useless_Use_O...


`TERM=vt100` or `TERM=dumb` used to work most of the time, but unfortunately piping through `cat` is increasingly necessary.


I use 9term (from plan9port[0]) as my standard terminal emulator. It has no support for colours. Plan9port comes with a command, nobs, which strips ANSI colour from output. Setting PAGER=nobs and TERM=dumb takes care of a lot of the colour outputting.

9term also does not support a lot of other terminal features. Using it I’ve noticed that there are two kinds of terminal programs:

1. Programs that uses the terminal as a GUI.

2. Programs that can be composed with other programs.

I prefer a program in category 2, since I like scripting to automate my tasks.

[0]: https://github.com/9fans/plan9port


If you don't want see color output, asking every program to follow a new standard is silly when you could easily handle it in one application. The terminal.


You could also pipe the output through a program that filters ANSI colour codes. That'd be an extremely simple utility and fix for the problem.


Extremely simple, and also wrong. Whether stdout is a pipe or a tty makes differences to programs, sometimes huge differences. For example, when connected to a tty, `git log` will use a pager when the output length exceeds the terminal height. With piping, it cannot do that.


Who doesn’t want color? Am I too young to understand why color would be bad!?


It's an experience thing. Color gets in the way in many cases. You need a way to turn it off. If you can't, then when you pipe it to a text file, it turns into garbage.

Worse, many programs break when you start getting fancy. If you would just stop trying to add color to your node programs, stop trying to add emojis, stop trying to control the entire terminal window, then suddenly everything would work much better. If you kick off multiple processes, you can simply console.log() instead of having to set up an RPC interface to communicate with the main process. (This actually happened.) If you stop putting emojis in your error messages, then WebStorm can highlight the stack traces automatically when you run in the debugger, enabling you to jump to the stack trace just by clicking on it. This breaks when you add emojis. (Also happened.) And if you stop adding color, then you can redirect to a file without screwing things up.

In short, stop getting fancy. :)


First thing I usually do on a new Linux system is dial down colors in “ls”. Default colors are ridicuously distacting and most don’t convey any new information. I like directories and symlinks highlighted. But the fact that a file is a .jpg or .tar.gz is sufficiently obvious from its name, without turning my terminal into a circus.

I similarly dislike the new trend of fancy command prompts. It’s a prompt, it should stay in the background.


If you're redirecting the output to a file or piping it into another program, the color just turns into annoying markup. Many programs handle this automatically but not all do.


In my opinion, any program outputing ANSI sequences without checking isatty() has a serious bug.


"I like strawberries, therefore everyone likes strawberries" is a strange way of thinking, but maybe it helps if you simply know that I don't like strawberries.

I simply find terminal programs that generate colour distracting.


Distracting from what? Are you just looking at the colors and nothing else as soon as there are any? I think colors are a great way to enhance output, as it is like a third dimension to formatting. Needless to say there might be tools that use them in silly ways, but for example having errors in red immediately can signal something bad happened.


> Distracting from what? Are you just looking at the colors and nothing else as soon as there are any?

Yes.

> I think colors are a great way to enhance output, as it is like a third dimension to formatting.

I don't. I view them as a OOB marker that causes the coloured content to effectively jump the queue into my brain.

> having errors in red immediately can signal something bad happened.

As a specific counter-example: I'm often interested in the log output that occurred right before something bad happened, so having errors in red is exactly what I don't want.


Don't know the details anymore, but the default experience on major Linuxen was to display plain files in blue color (eg. when listing files using the ls command). So that when you switched to an inverse (white-on-black) video setting from the default black-on-white, you had a hard time to read blue-on-black text for one of the most basic tasks on the command line without resorting to customize terminal colors. Don't know who came up with such a usability fail.


The fundamental problem is how terminal colors are specified. The old non-color terminals had brightness and bold. The first color terminal, setting the standard, had just 8 colors without brightness control. Put those together, and you have 16.

The result is not what you'd like. You'd really like to specify an overall scheme (light on dark, or dark on light) and then hues for each character displayed.

That'd let you see green on green just fine. It wouldn't even be possible for the foreground and background to be identical, because one would be light and one would be dark.

I suppose that switching everybody over might not be as hard as I thought at first. Considering systemd, it only takes a manager at Red Hat to force a new standard. I sure would appreciate it.


Nice to see someone mention this. Sometimes I think I am the only one. This sort of thing is what scares me away from GNU/Linux whenever I try it, having spent so many years with a BSD that does not enable anything by default. Nothing wrong with customization, except when it is someone other than the user who is fiddling with it.

I am used to a black background. Seems like the logical "default" starting point in VGA textmode. Even Linux kernel output when booting starts on a black blackground.


For my part, the most obvious irritation is that some tools assume your terminal has a black background. I run them with the default configuration and end up with the most critical bits of info in yellow-on-white text. Maddening.

(I do know the colours can be adjusted in the terminal config, and many tools have options to switch to a white background. Would be nice if the defaults worked better though.)



As I colorblind, I don't want to deal with colors anymore. But I'm old.



Unless I specifically ask for color, I don't.


This is not a general solution as the author wants, but when I know my own utilities are going to be redirected or piped and I don't want ANSI/colour sequences captured then I've wrapped the ANSI sequences in logic like this: (Python example)

`if sys.stdout.isatty(): ...`

I recognize TTY != ANSI in some cases. And sometimes you actually want control sequences captured or redirected. So this is far from perfect but it might be good enough for some.

Such a check ports across systems well and doesn't rely on a new environment variable.


Can't you just turn off ANSI colors in your terminal emulator?


http://bixense.com/clicolors/

Looks like this is already supported by more software; rather than an n+1 standard (https://xkcd.com/927/), why not use this one instead?


Quoting a comment I made at https://github.com/rust-lang/rust/pull/27867#issuecomment-22... about that:

One other potential issue with this (an issue that also applies to GNU make's MAKE_TERMOUT and MAKE_TERMERR environment variables, documented at https://www.gnu.org/software/make/manual/make.html#Terminal-...): what happens if someone sets CLICOLOR_FORCE or MAKE_TERMOUT to indicate that output will (eventually) go to a terminal for output, but then some portion of the build system actually does want to redirect output to a file or pipe that won't eventually get printed to a terminal? Does that part of the build system then need to explicitly unset CLICOLOR_FORCE and MAKE_TERMOUT and any other variable the program might potentially respect, to make sure it won't include color in its output? That seems likely to produce breakage.

Consider if grep respected CLICOLOR_FORCE or MAKE_TERMOUT. What would happen if a build system set one of those, and then somewhere deep in the build system (or even in a shell script called from the build system), someone ran grep in a pipeline, along with various other text processing commands? If grep respected those environment variables, then that pipeline would break.

I do like the idea of having a standard way to tell a program "no, really, your output will wind up on the terminal, please print in color even though it doesn't look like a TTY". However, I don't think it makes sense to do so without a solution for this problem. Not showing color output is an annoyance; breaking a build by printing color escape sequences to a pipe would be far worse.

(This is also part of why programs like grep are removing environment variables like GREP_OPTIONS: they break scripts.)


Does that part of the build system then need to explicitly unset CLICOLOR_FORCE and MAKE_TERMOUT

Yes, it should be the responsibility of the build system to control the environment variables set during the build.

What would happen if a build system set one of those, and then somewhere deep in the build system (or even in a shell script called from the build system), someone ran grep in a pipeline

The person adding the 'grep' would need to be aware of whether the build system is using color output or not.

This is also part of why programs like grep are removing environment variables like GREP_OPTIONS: they break scripts.

This seems unfortunate; scripts could just unset GREP_OPTIONS if they care.


> This seems unfortunate; scripts could just unset GREP_OPTIONS if they care.

grep is portable, and much older than GREP_OPTIONS. A script shouldn't be expected to fix any random non-standard idiosyncrasy of the local version of grep.


Fair enough; since GREP_OPTIONS seems only useful for interactive sessions, perhaps non-interactive shells should purge it from the environment (e.g. with BASH_ENV).

It would be great if grep could figure out whether its parent process is an interactive shell or a script, but there doesn't seem to be a reliable way to do that.


I like your solution further down in the Rust pull request:

programs like make could collect output using a pty rather than a pipe or temp file

This seems brilliant. The pipe mechanism is too dumb to differentiate between these cases - Unix needs a smarter pipe, and pty could be it. Maybe there could be another character in the shell for a pipe that's really a pty like '_', or a digraph like '|p'.


Yeah, that's a pretty reasonable concern. Environment variables can be problematic because they are usually inherited when spawning processes, and many build systems rely on this for things like passing through compiler flags.

I think that just having the CLICOLOR option would be reasonable, for enabling or disabling color to a TTY, but CLICOLOR_FORCE is more problematic.


> I think that just having the CLICOLOR option would be reasonable, for enabling or disabling color to a TTY, but CLICOLOR_FORCE is more problematic.

Yeah, I'd agree with that.


As someone else pointed out, I think NO_COLOR should be COLOR (my preferred name, and I've used it in many of my scripts) or CLICOLOR or whatever, to be able to force turning off or turning on colors.


Is something wrong with the HN dupe detector?

I posted this same link 2 days ago: https://news.ycombinator.com/item?id=16305172


The dupe detector is deliberately porous...

https://hn.algolia.com/?query=dang%20deliberately%20porous&s...


sed "s,\x1B\[[0-9;]*[a-zA-Z],,g"


wouldn't it be easier to modify your terminfo database to make color unavailable?


That only works for applications that uses terminfo. Most don't; VT100/ANSI escape sequences are universally supported nowadays, and a lot of programs just hard-code that.


Plenty of stuff doesn't even check for terminfo (doesn't even check for a TTY) and just dumps ANSI escape sequences over the wire. Like, say, into a file. Which makes grepping it fun later.


This doesn't make sense. There's no point in disabling color, and even if we need we can just pass the de-facto standard option. The homebrew guy did the right thing, and putting it on the list like "hall of shame" is definitely is not a good idea.


> There's no point in disabling color,

As someone else said, "I like strawberries, therefore everyone likes strawberries". A quick summary of potential reasons:

- it's distracting (https://news.ycombinator.com/item?id=16323038)

- colorblindness (https://news.ycombinator.com/item?id=16322796)

- bad default color schemes (https://news.ycombinator.com/item?id=16322812)

- escape codes may break text processing (https://news.ycombinator.com/item?id=16322600)


Homebrew doesn't have an option at all to disable color.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: