bash - Cleanup after the background process finished its work on Linux -


i have script-launcher (bash) executes python scripts in background, can start , close terminal/ssh connection, leaving script working.

it accepts name of script run , optional arguments pass there. starts python script (detached) , creates file pid (of python script) in same directory, can later reconnect server , kill background process using pid file.

also pid file used prevent same script been started if it's running (singleton).

the problem can't figure out how delete pid file after python script finished work. need implemented in bash script, no python solutions (since want use cases) or screen tool. supervisor (that delete pid file after script finished work) should run in background (!), can same thing: close terminal session.

what i've tried far:

#!/bin/bash  pidfile=$1.pid  if [ -f $pidfile ];     echo "process running, pid: $(< $pidfile)"     exit 1 else     nohup python $1 "${@:2}" > /dev/null 2>&1 &     pid=$!     echo $pid > $pidfile     # supervisor     nohup sh -c "wait $pid; rm -f $pidfile" > /dev/null 2>&1 & fi 

in example pid file deleted immediately, because wait command returns (i think it's because new process isn't child of current one, wait doesn't work in case expect).

do have thoughts how can implemented? basically, need replace line

nohup sh -c "wait $pid; rm -f $pidfile" > /dev/null 2>&1 & 

that wait until previous script (python's in case) finish work , delete pid file.

upd: ok, problem wait command, because can't wait non-child processes. working solution replace while loop:

#!/bin/bash  function cleanup {     while [ -e /proc/$1 ];         sleep 1;     done     rm -f $pidfile }  pidfile=$1.pid  if [ -f $pidfile ];     echo "process running, pid: $(< $pidfile)"     exit 1 else     python $1 "${@:2}" > /dev/null 2>&1 &     pid=$!     echo $pid > $pidfile     cleanup $pid > /dev/null 2>&1 &     disown fi 

for shell scripts, use traps:

#!/bin/bash function finish {     wait $pid     rm $pidfile > /dev/null 2>&1 & }  trap finish            exit trap "exit 2; finish"  sigint  pidfile=$1.pid  if [ -f $pidfile ];     echo "process running, pid: $(< $pidfile)"     exit 1 else     nohup python $1 "${@:2}" > /dev/null 2>&1 &     pid=$!     echo $pid > $pidfile fi 

traps allow catch signals , respond them, in code above, exit signal (normal completion) execute finish, removing $pidfile. on sigint (user requested exit ctrl-c), script remove $pidfile , exit 2.

directly in python: if want handle manually take @ atexit. haven't looked @ source, looks implements traps in order register cleanup functions:

import atexit import os   def cleanup():     os.unlink(pidfile)   atexit.register(cleanup) 

or automate pidfile handling checkout pid handle preventing simultaneous execution on own:

from pid import pidfile  pidfile():   do_something() 

or better yet

from pid.decorator import pidfile  @pidfile() def main():   pass  if __name__ == "__main__":   main() 

Comments