I'm writing a collection of scripts to talk to an external program. My problem is that the scripts are only "alive" for a short time (triggered by a keypress in a larger program) but the external program needs to stay running between calls, and was originally designed for interactive use (think debugger).

  • If I just wanted to write a single script to run the program, I'd open a PTY to it and send/receive data on that. This works (my scripts are in LUA and lpty can deal with the PTY) but it can't keep the program running when the script terminates.

  • If the external program offered me a socket to connect on (like gdb does), I could just save the name somewhere and have each script connect to that socket. But it was only meant to be used interactively.

I could write a daemon that starts the external program, opens a PTY to it and then listens on a socket itself. The scripts could then connect to the daemon's socket and send data, which the daemon would forward to the program over the PTY and send the results back.

The format of the data I'm exchanging with the external program is line-based, but I don't know in advance how many lines I'm going to get back from a single command. Not a problem with a PTY, but a bit more work with luasocket.

I'm wondering if there isn't a better way to do this. Can I somehow open a PTY to a program and get its "address", from which I can later connect and disconnect multiple times from my scripts? (Only one script can ever run at a time so concurrency is not a problem.) That would avoid using sockets at all.

Or is there some combination of options in socat that does exactly this already?

  • Have you looked at man openvt?
    – goldilocks
    May 15, 2015 at 9:25
  • openvt seems to require sudo on this machine (Ubuntu trusty; without root I get: Couldn't get a file descriptor referring to the console) so this isn't an option.
    – user21105
    May 15, 2015 at 9:35
  • Actually it doesn't look like it works with ptys anyway -- but you can write to any pty you own pretty simply. Find the node with tty and then try, e.g. ls -l > /dev/pts/8 from another terminal.
    – goldilocks
    May 15, 2015 at 9:41

1 Answer 1


You can't “open a PTY to a program”. A PTY is a pseudo-terminal; it requires a terminal end. If you want to communicate with a program directly via a terminal, the program would need to create a terminal (i.e. to behave like a terminal emulator).

Instead, you can run the program in a terminal, such as screen. Screen makes it easy to inject input and read output from programs.

However, for what you're doing, a terminal would introduce useless complications. A socket is exactly the right tool for what you want to do — direct bidirectional communication between two programs. (For unidirectional communication, a pipe would be the right tool.) The only advantage of using a terminal is if you don't control one of the ends and it insists on buffering output by block rather than by line if the output isn't on a terminal.

  • I've tried opening a pair of read/write pipes to the target program. My problem here is that if I want to check whether there's any new data available (with a lua read(0)), it blocks if there is no data to read from the pipe. This isn't very useful for a "have I read everything" check, that's why I was using lpty.
    – user21105
    May 18, 2015 at 10:28
  • @Bristol At the system call level, you can make reading non-blocking in exactly the same way for a terminal as for a pipe. Maybe Lua doesn't expose this and has a different API that works only for terminals? I'm not familiar with Lua's API. In any case, the normal way to read from multiple sources is not with a non-blocking read, but with select or poll to find out in advance which sources have data available. May 18, 2015 at 12:48
  • Ok, thanks. It seems like I may need to dig further into the libraries I'm using.
    – user21105
    May 18, 2015 at 13:31

You must log in to answer this question.