stop python program when ssh pipe is broken
linux, python, ssh
Solution
I'd suggest periodically logging to stderr.
This will cause an exception to occur when you no longer have a stderr to write to.
Problem
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 sys while True: print time.time() sys.stdout.flush() time.sleep(1) ``` local_script: ``` #!/usr/bin/env python from subprocess import Popen, PIPE import time p = Popen(['ssh','-tt','user@foo','remote_script'],stdout=PIPE) while True: line = p.stdout.readline().strip() if line: print line else: break time.sleep(10) ``` First of all, the output is really weird, it seems to keep adding tabs or something: ``` [user@local ~]$ local_script 1393608642.7 1393608643.71 1393608644.71 Connection 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.