I'm writing a python script with an infinite while loop that I am running over ssh. I would like the script to terminate when someone kills ssh. For example:
The script (script.py):
while True:# do something
Will be run as:
ssh foo ./script.py
When I kill the ssh process, I would like the script on the other end to stop running.
I have tried looking for a closed stdout:
while not sys.stdout.closed:# do something
but this didn't work.
How do I achieve this?
Edit:
The remote machine is a Mac which opens the program in a csh:
502 29352 ?? 0:00.01 tcsh -c python test.py
502 29354 ?? 0:00.04 python test.py
I'm opening the ssh process from a python script like so:
p = Popen(['ssh','foo','./script.py'],stdout=PIPE)while True:line = p.stdout.readline()# etc
EDIT
Proposed Solutions:
- Run the script with
while os.getppid() != 1
This seems to work on Linux systems, but does not work when the remote machine is running OSX. The problem is that the command is launched in a csh (see above) and so the csh has its parent process id set to 1, but not the script.
- Periodically log to
stderr
This works, but the script is also run locally, and I don't want to print a heartbeat to stderr
.
- Run the script in a pseduo tty with
ssh -tt
.
This does work, but has some weird consequences. Consider the following:
remote_script:
#!/usr/bin/env python
import os
import time
import syswhile True:print time.time()sys.stdout.flush()time.sleep(1)
local_script:
#!/usr/bin/env python
from subprocess import Popen, PIPE
import timep = Popen(['ssh','-tt','user@foo','remote_script'],stdout=PIPE)while True:line = p.stdout.readline().strip()if line:print lineelse:breaktime.sleep(10)
First of all, the output is really weird, it seems to keep adding tabs or something:
[user@local ~]$ local_script
1393608642.71393608643.711393608644.71Connection to foo closed.
Second of all, the program does not quit the first time it receives a SIGINT
, i.e. I have to hit Ctrl-C twice in order to kill the local_script.