Understand why colors disappear with pipes

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the bash category.

Last Updated: 2024-12-03

Color codes from command line tools often appear or disappear depending on the context from which you call a command. This is in order to distinguish between interactive user-facing shell usage vs. usage as part of a pipeline of commands. In the later case we do not want to send color escape codes as they will often interfere with the data processing. Usually we only add these at the last possible moment before displaying on the screen.

FYI: Unwanted color escape codes, in the wrong place, show up as additional characters. For example here is the text application.rb with color codes:

\e[31mapplication.rb\e[0m"

So how is this decision made whether or not to show color?

Basically, when you are piping or sending to STDOUT, color is usually disabled. That's why piping into less or grep means commands that previously had colors lose them.

But you can change this behavior by explicitly telling the command your color preference, e.g. if you type jq --color-output ... | less, this will always output colors, even though it was piped.