I need to launch a server on the remote machine and retrieve the port number that the server process is lsitening on. When invoked, the server will listen on a random port and output the port number on stderr.
I want to automate the process of logging on to the remote machine, launching the process, and retrieving the port number. I wrote a Python script called ‘invokejob.py‘ that lives on the remote machine to act as a wrapper that invokes the job and then returns the port number, it looks like this:
import re, subprocess executable = ... # Name of executable regex = ... # Regex to extract the port number from the output p = subprocess.Popen(executable, bufsize=1, # line buffered stderr=subprocess.PIPE ) s = p.stderr.readline() port = re.match(regex).groups()[0] print port
If I log in interactively, this script works:
$ ssh remotehost.example.com Last login: Thu Aug 28 17:31:18 2008 from localhost $ ./invokejob.py 63409 $ exit logout Connection to remotehost.example.com closed.
(Note: successful logout, it did not hang).
However, if I try to invoke it from the command-line, it just hangs:
$ ssh remotehost.example.com invokejob.py
Does anybody know why it hangs in the second case, and what I can do to avoid this?
Note that I need to retrieve the output of the program, so I can’t just use the ssh ‘-f’ flag or redirect standard output.
I suspect it’s the above line. When you invoke a command directly through ssh, you don’t get your full pty (assuming Linux), and thus no stderr to read from.
When you log in interactively, stdin, stdout, and stderr are set up for you, and so your script works.