26

Test environment:

$ mkdir testdir
$ cd testdir
$ echo | tee "file 
name"

Now, ls will print file?name (under Ubuntu GNU bash, at least), while ls | cat will print file and name in separate lines.

What I'd like to achieve is, print file?name with the piped version, so something like

$ something ls | cat` or `ls | something | cat` or `ls | something cat

In other words, how to fool a command like ls here into thinking, it has a TTY, when it does not, in the shell?

Note: ls is just an example program here, I'm looking for generic solution, not program specific like ls -q | cat would be.

Michael Homer
  • 76,565
hyde
  • 1,288
  • 1
  • 13
  • 20

1 Answers1

25

You can use socat to simulate a pseudo terminal (pty):

socat - EXEC:'ls --color=auto',pty,setsid,ctty | cat

There are many more option, see its documentation.

ls uses by default the width of the terminal for columnwise output. I found not yet a way, how to set this on a socat pty, a workaround is to use the ls option -w WIDTH.

jofel
  • 26,758
  • 1
    You can do stty rows X cols Y inside the session to set the size of the terminal. Note that tput lines and tput cols query STDERR, while stty sets the state on STDIN, so make sure you pass the stderr option to socatas well if you want to checkthat way (this confused me at first !) – laanwj May 28 '19 at 16:27
  • 1
    I'm constantly amazed by the power of socat. I don't need it often. It only seems to come up when I'm attempting the impossible, but it never disappoints. – ivan May 29 '19 at 00:46