Search code examples
linuxmacospyserialtmuxtty

Is it possible to programmatically read the `stdout` of another pty / tty without affecting its behavior?


I am attempting to programmatically read the output written by an application running in a specific tmux pane, so that I can determine when to send-keys to it from a controlling process.

In particular, I would like to automatically enter a password, but I do not want to enter it until I am sure the password prompt has appeared.

My current attempt has been to use tty to find the controlling tty, and then pass it to pyserial to try to read, since it appears to be able to read tty's. Note that in the real application, I have other ways of finding out the tty.

Unfortunately, as soon as I run the following code, the target tmux pane immediately closes.

import serial
ser = serial.Serial('/dev/ttys013', timeout=1)

Is it possible to read from a pty this way?

I am running on OSX, but would appreciate a solution that works on both Linux and OSX.


Solution

  • Typically, with python you would use pexpect to start the program and interact with it via a pty, but if you already have a program running in tmux you could simply use tmux's pipe-pane command to save a copy in a file of what is written to the screen. For example, for a pane number 1 you can give the shell command:

    tmux pipe-pane -t 1 'cat >/tmp/capture'
    

    and then tail the file /tmp/capture. (Use tmux pipe-pane -t 1 to stop). To avoid polling, you can use a fifo instead.