0

Many CLI programs produce different output when they print to the console as opposed to being piped to another program. For example, exa will print a list of files with color highlighting. But exa | less will not have colors.

I am aware that often these programs have arguments to force one kind of input or the other, so the workaround is to learn those arguments and use them when piping. This isn't a general solution because of several problems:

  • You have to learn the arguments of every single command, or you have to keep getting distracted from your workflow to read a manpage when you're just trying to pipe some stuff.
  • Not all programs provide such arguments.
  • Having to keep inserting the arguments into a long chain of pipes is annoying. Sometimes the whole chain takes a long time to run, so by the time you've seen the incorrect output and realized you forgot to add --color or whatever again, you've already wasted minutes of time.

Clearly the design of the program was that it would detect that it is being piped and guess that a different output is appropriate, which is fine and correct behavior in many cases. In many other cases the program's guess is wrong. Instead of having to learn the unique interface of each program and override the guess, it seems like it would be more efficient if you could simply pre-empt the guessing by not telling the program it is being piped in the first place.

Is this possible? What is a universal method of piping the output of a program, while making the program think it is printing to the console and produce the same output that it would have without the pipe?


If the answer depends on the shell, I am interested in the following shells:

  • bash since it is the de facto standard
  • zsh since it is a common bash-compatible upgrade
  • fish since it is an example of attempting to improve on bash without compatibility

Based on https://askubuntu.com/a/482826 it seems like the problem is that isatty is false when the program is piped. So the solution could be somehow piping the command with isatty still being true. I don't see how I could actually accomplish this, though.

1
1

Not sure if this is a good solution, but based on https://stackoverflow.com/questions/4233808/piping-data-to-linux-program-which-expects-a-tty-terminal it seems like unbuffer accomplishes this.

unbuffer exa | less will show colors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.