Return value of background process

2019-06-19 01:28发布

I need to take some action based on the return value of a background process ie if it terminates in the first place.

Specifically : in ideal operation, the server which I run as the background process will just keep running forever. In such cases keeping it in the background makes sense, since I want my shell script to do other things after spawning the server. But if the server terminates abnormally, I want to preferably use the exit return value from the server to decide whether to kill my main script or not. If that's not possible I at least want to abort the main script rather than run it with a failed server.

I am looking for something in the nature of an asynchronous callback for shell scripts. One solution is to spawn a monitoring process that periodically checks if the server has failed or not. Preferably I would want to do it without that within the main shell script itself.

3条回答
\"骚年 ilove
2楼-- · 2019-06-19 02:08

You can use shell traps to invoke a function when a child exits by trapping SIGCHLD. If there is only one background process running, then you can wait for it in the sigchld handler and get the status there. If there are multiple background children running it gets a little more complex; here is a code sample (only tested with bash):

set -m # enable job control
prtchld() {  
  joblist=$(jobs -l | tr "\n" "^")
  while read -a jl -d "^"; do
    if [ ${jl[2]} == "Exit" ] ; then 
      job=${jl[1]} 
      status=${jl[3]}  
      task=${jl[*]:4}
      break  
    fi  
  done <<< $joblist
  wait $job 
  echo job $task exited: $status
}
trap prtchld SIGCHLD

(sleep 5 ; exit 5) &
(sleep 1 ; exit 7) &

echo stuff is running

wait
查看更多
Animai°情兽
3楼-- · 2019-06-19 02:09

You could nest the background process inside a script. For example, if the process you wish to send to the background is called foo:

#!/bin/sh

foo

if [ $? ]
then 
    # do something here if process failed
fi

Then just run the above script in the background instead of foo. you can kill it if you need to shut it down, but otherwise it will never terminate as long as foo continues to run, and if foo dies, you can do whatever you want to based on its error code.

查看更多
Anthone
4楼-- · 2019-06-19 02:13

I like the first one better for my purpose, I presume in the "do something here if process failed" I can kill the script that called this wrapper script for foo by using it's name.

I think the first solution works well for multiple children. Anyway, I had to get this done quickly, so I used a hack which works for my application:

I start the process in background as usual within the main script, then use $! to get it's pid ( since $! returns last bg pid), sleep for 2 seconds and do a ps -e | grep pid to check if the process is still around based on the return value of (ps -e | grep pid). This works well for me because if my background process aborts it does so immediately ( because the address is in use).

查看更多
登录 后发表回答