26

I have a program in Linux which refuses to run if its stdin/stdout is not a TTY (terminal device). Is there an easy-to-use tool which will create a PTY, start the program with the newly created TTY, and copy all data over stdin/stdout?

The use case is not interactive, but scripting. I'm looking for the most lightweight solution, preferably not creating TCP connections, and not requiring too many other tools and libraries to be installed.

pts
  • 80,836
  • 20
  • 110
  • 183

2 Answers2

38

unbuffer, part of expect (sudo apt-get install expect-dev on Ubuntu Lucid), can fool a program into thinking it's connected to a TTY.

$ tty 
/dev/pts/3
$ echo | tty 
not a tty
$ echo | unbuffer tty 
/dev/pts/11
pts
  • 80,836
  • 20
  • 110
  • 183
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • There is a non-production-ready (does not exit properly) reference implementation of unbuffer.c here: http://www.man7.org/tlpi/code/online/dist/pty/unbuffer.c.html I could get the source code (unbuffer.c) from here: http://www.man7.org/tlpi/code/download/tlpi-101113-dist.tar.gz . – pts Nov 20 '10 at 17:30
  • 1
    On Mac OS, using homebrew, `unbuffer` can be installed with `brew install expect` – forivall Jun 10 '19 at 17:53
1

You can use socat for this: echo your stdin strings | socat EXEC:"your_program",pty STDIO >/stdout_file

For example with bash: echo ls | socat EXEC:'bash',pty STDIO >/tmp/ls_out

Or as described here, for a program run with docker:

# Run the docker task, here bash, in background
docker run -it --rm --name test ubuntu &
# Send "ls -la" to the bash running inside docker
echo 'ls -la' | socat EXEC:'docker attach test',pty STDIN
# Show the result
docker logs test
Anthony O.
  • 22,041
  • 18
  • 107
  • 163