DEV Community

Discussion on: Finding the other end of a pipe on Linux

Collapse
 
jselbie profile image
John Selbie • Edited

Most console tools detect color support by interrogating the output terminal for color support with a few system calls. Read this

That is, the source process that generates the original text is just not including the color escape chars when it detects that it's not on a color terminal.

Some programs can be forced to output color chars with a command line parameter.

Try this on the command line:

ls -1 | sort

The above produces a list of files in typical order. However, the color output normally generated by ls isn't present.

Now try this:

ls -1 --color=always | sort

And it appears to work. The filenames have color. But the sort program gets confused. It interprets the filenames with leading escape chars as it would any other string. The side effect is that the sort program does not show my files in alphabetical order. Instead, it lists the files sorted by color (with alphabetical order as a secondary sort).

There's probably some clever ways in which a downlevel process taking piped input might be able to emulate a color tty to fool the upstream process into generating color chars. Or a fake tty driver that functions as a pipe between both programs. It would not surprise me at all if such a thing already exists.

Collapse
 
hoelzro profile image
Rob Hoelz

That is, the source process that generates the original text is just not including the color escape chars when it detects that it's not on a color terminal.

Right - I'm wondering if we could improve upon this further in the case involving pipes, by having a downstream process advertise its support for handling color. To piggyback off of your sort example, it would be neat if sort could know to strip the ANSI color escape sequences off of its input, and inform the upstream process "hey, you can send me colored output!" Two approaches I thought about were enhancing fgetxattr to work on pipes in the kernel, or decoupling display information from the output stream entirely - but those both deserve their own posts! What I had in mind with this post was a simple whitelist - eg. have ack keep automatic coloration if being piped to less with the -R flag active.
I probably should've mentioned this example!

There's probably some clever ways in which a downlevel process taking piped input might be able to emulate a color tty to fool the upstream process into generating color chars.

Sadly, I think that the granularity of stat prevents this - I'm guessing that most programs (checked by straceing a program using isatty), either directly or indirectly, fstat standard output, and then check the file type of the resulting structure. What one could do is wrap the upstream program in a pseudo TTY using a helper program (something like ptyget) to fool that program, but then the downstream program would still need to handle the colored input.