4

I have a bunch of scripts that are used to start similar processes across a number of servers. I'd like to condense them down to one Python script called 'START', but something weird is happening when it's run over ssh.

$ ./START APP_A works as expected: APP_A is launched and begins doing its thing. Control is returned to the console immediately (before APP_A terminates).

$ ssh localhost /path_to/START APP_A sort of works: APP_A is launched and begins doing its thing, but ssh doesn't print any output to the screen or return control to the console until after APP_A terminates.

I assume it's a problem with signals or file handles, but I'm at a loss. Here's the Popen call that seems to be causing the trouble:

sub = subprocess.Popen(shlex.split(cmd), stdout=open(file_out, 'a+'), stderr=subprocess.STDOUT, close_fds=True)
print 'New PID:', sub.pid

I'm using Python 2.4.3 on RHEL.

EDIT: Wrapping the Python script seems to work:

DIR="$( cd "$( dirname "$0" )" && pwd )"
pushd $DIR >> /dev/null
./START $1 &
popd >> /dev/null
dmcauslan
  • 398
  • 2
  • 8

3 Answers3

0

Don't use shlex to call in conjunction with subprocess. It doesn't do what you expect. Instead, give subprocess a Python list of the command, like

subprocess.Popen(['/some/program', 'arg1', 'arg2', 'arg3'])
Community
  • 1
  • 1
phihag
  • 278,196
  • 72
  • 453
  • 469
  • How would launching the script from ssh vs. calling it directly be affected by this? The script works fine when called directly. – dmcauslan Sep 27 '11 at 15:53
0

When you do:

ssh some_host remote_command remote_cmd_param

then it is normal that ssh does not return control before remote_command is done. If you want otherwise you need to sent it to background aby adding & at the end.

ssh redirects stdout of remote_command to its (local) stdout. If you don't see any output this may be because remote_command does not set any to stdout but tries to send it to the console for example. This is why you cannot do:

ssh remote_host mc # or any other command using terminal
Michał Šrajer
  • 30,364
  • 7
  • 62
  • 85
  • The START script does output some debugging information that gets printed to STDOUT using print. When I call the script directly, the program displays this information and exits. When I call the script via ssh, it only prints the information once the subprocess terminates. The subprocess itself logs other data to its own stdout (set explicitly in the Popen call). – dmcauslan Sep 27 '11 at 15:57
0

You should put this in START_APP_A

nohup /path/to/APP_A >/path/to/log 2>&1 </dev/null &

Then it will work, and all the output from APP_A will go into a log file which you can inspect when you need to.

Note that if you need to inspect this output while APP_A runs, then you need to change APP_A so that it flushes stdout after printing or else change stdout to be unbuffered.

Michael Dillon
  • 31,973
  • 6
  • 70
  • 106
  • Doesn't "stdout=open(file_out, 'a+'), stderr=subprocess.STDOUT" already redirect the IO? – dmcauslan Sep 27 '11 at 15:51
  • Maybe it does, and maybe it doesn't. When you wrap it with a shell script, it works so why not just use the shell. In addition, it is not clear to me which bits you are running locally and which bits are running remotely. One thing that you missed is stdin which may or may not be important. In any case, that one line of shell script will work with any app in any language to run it on a remote server that you have connected to with ssh. Read the man page for nohup to learn more. – Michael Dillon Sep 28 '11 at 05:05