Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

set -e and background process

Tags:

bash

shell

In my script I set set -e to stop processing if an error occurs. It works well for all commands running in foreground, but some of my commands must be run in parallel in background. Unfortunately if background process fails the script is not stopped although set -e flag.

Example with foreground process works.

#!/bin/bash
set -e
ls -l no_file
sleep 100

Example with background process does not work.

#!/bin/bash
set -e
ls -l no_file &
sleep 100

How to handle failures of the background processes?

like image 784
Marcin Avatar asked Feb 22 '17 10:02

Marcin


1 Answers

Starting a command asychronously (with &) always returns exit status 0. To get the actual exit status of the command use the builtin wait. A simple example:

$ (sleep 5; ls -l nofile) &
[1] 3831
$ echo $?
0
$ wait -n
ls: cannot access 'nofile': No such file or directory
[1]+  Exit 2                  ( sleep 5; ls --color=auto -l nofile )
$ echo $?
2

wait -n waits for any child process (which can be very useful). If you want to wait for a specific process, you can capture the PID when you start it -- it's in the special variable $! -- then wait by PID:

$ (sleep 5; ls -l nofile) &
$ myjobpid=$!
$ # do some other stuff in parallel
$ wait ${myjobpid}
ls: cannot access 'nofile': No such file or directory
[1]+  Exit 2                  ( sleep 5; ls --color=auto -l nofile )

The relevant section of the Bash manual is titled "Job control"

like image 78
AlexP Avatar answered Sep 21 '22 15:09

AlexP