1515# - wait_forever will be waiting forever after exiting all commands.
1616# Usefull in case of daemons which are detaching and exiting
1717
18-
1918set +e # Do not exit on errors by default
2019if [ " $RC_DEBUG " = " true" ]; then
2120 set -x # Turns on Debug mode if true
2221fi
2322: ${RC_WAIT_POLICY:= wait_any} # Sets default value for a wait policy
2423
2524main () {
26- trap hook_main_exit EXIT
27- trap ' exit' INT
25+ trap ' _exitcode=$?; hook_main_exit; exit $_exitcode' EXIT
2826
2927 export SELF_NAME=$( basename -s .sh $0 ) # Self name for logging purpose
3028 export DIR_NAME=$( dirname $0 )
3129 export MAINPID=" $BASHPID " # PID of the main process
3230 childpid=" " # Collecting child processes
3331 ns=" main" # Name Space
34- local _wait_bg_cmd _file
32+ local _wait_bg_cmd _file _exitcode=0 _exitcode2=0
3533
3634 case " $RC_WAIT_POLICY " in
3735 wait_all) _wait_bg_cmd=" command -p wait" ;;
3836 wait_any) _wait_bg_cmd=" command -p wait" ;;
39- * ) _wait_bg_cmd=" " ;;
37+ * ) _wait_bg_cmd=" : " ;;
4038 esac
4139
4240 say " The default wait policy: $RC_WAIT_POLICY "
4341
4442 # Reads commands from files to run on the background (in parallel)
4543 for _file in $( ls $DIR_NAME /trc.bg.* 2> /dev/null) ; do
4644 (
47- trap ' hook_sub_exit "$_file"' EXIT
45+ # Run this on any exit, catching the exitcode of the "main" command,
46+ # printing additional info and finishing up this sub-program with the right exitcode
47+ trap ' _exitcode=$?; hook_sub_exit $_exitcode "$_file"; exit $_exitcode' EXIT
48+
49+ # In case of exit on errors (set -e), catch exitcode and exit with it, which
50+ # will lead to triggering an EXIT trap
51+ set -e
52+ trap ' exit $?' ERR # Exit with the status code of a last command
53+
4854 ns=" bg"
49- set -e # Exit on errors in the sub-shell
5055 say " Running on the $( ns_long $ns ) : $_file "
5156 . $_file
5257 )&
@@ -57,9 +62,16 @@ main() {
5762 while [ " $1 " = " -D" ]; do
5863 shift
5964 (
60- trap ' hook_sub_exit "$1"' EXIT
65+ # Run this on any exit, catching the exitcode of the "main" command,
66+ # printing additional info and finishing up this sub-program with the right exitcode
67+ trap ' _exitcode=$?; hook_sub_exit $_exitcode "$1"; exit $_exitcode' EXIT
68+
69+ # In case of exit on errors (set -e), catch exitcode and exit with it, which
70+ # will lead to triggering an EXIT trap
71+ set -e
72+ trap ' exit $?' ERR # Exit with the status code of a last command
73+
6174 ns=" bg"
62- set -e # Exit on errors in the sub-shell
6375 say " Running on the $( ns_long $ns ) : $1 "
6476 eval " $1 "
6577 )&
@@ -70,30 +82,57 @@ main() {
7082 # Checks for foreground tasks in files (sequentially)
7183 for _file in $( ls $DIR_NAME /trc.fg.* 2> /dev/null) ; do
7284 (
73- trap ' hook_sub_exit "$_file"' EXIT
85+ # Run this on any exit, catching the exitcode of the "main" command,
86+ # printing additional info and finishing up this sub-program with the right exitcode
87+ trap ' _exitcode=$?; hook_sub_exit $_exitcode "$_file"; exit $_exitcode' EXIT
88+
89+ # In case of exit on errors (set -e), catch exitcode and exit with it, which
90+ # will lead to triggering an EXIT trap
91+ set -e
92+ trap ' exit $?' ERR # Exit with the status code of a last command
93+
7494 ns=" fg"
75- set -e # Exit on errors in the sub-shell
7695 say " Running on the $( ns_long $ns ) : $_file "
7796 . $_file
7897 )
98+ # Catch the exitcode of a foreground sub-program
99+ _exitcode=$?
79100 done
80101
81102 # Checks for a foreground task in the command line (one parameter with all commands)
82103 if [ -n " $* " ]; then
83104 (
84- trap ' hook_sub_exit "$@"' EXIT
105+ # Run this on any exit, catching the exitcode of the "main" command,
106+ # printing additional info and finishing up this sub-program with the right exitcode
107+ trap ' _exitcode=$?; hook_sub_exit $_exitcode "$@"; exit $_exitcode' EXIT
108+
109+ # In case of exit on errors (set -e), catch exitcode and exit with it, which
110+ # will lead to trigger an EXIT trap
111+ set -e
112+ trap ' exit $?' ERR # Exit with the status code of a last command
113+
85114 ns=" fg"
86- set -e # Exit on errors in the sub-shell
87115 say " Running on the $( ns_long $ns ) : $@ "
88116 " $@ "
89117 )
118+ # Catch the exitcode of a foreground sub-program
119+ _exitcode=$?
90120 fi
91121
92- $_wait_bg_cmd
122+ # Wait for all background processes and exit with a status of the last one
123+ # or with 128+SIGNAL in case of getting a signal
124+ $_wait_bg_cmd $childpid ;
125+ _exitcode2=$?
126+
127+ if [ $_exitcode2 -ne 0 ]; then
128+ _exitcode=$_exitcode2 # update exit code only if one of background processes has failed
129+ fi
93130
94131 if [ " $RC_WAIT_POLICY " = " wait_forever" ]; then
95132 infinite_loop
96133 fi
134+
135+ return $_exitcode
97136}
98137
99138say () {
@@ -128,10 +167,16 @@ hook_main_exit() {
128167 fi
129168 done
130169 say " Exited."
170+
171+ # It's not needed to exit with a proper exit code here.
172+ # The programm will exit with correct exit code from EXIT trap of main()
131173}
132174
133175hook_sub_exit () {
134- local _rc=$?
176+ set +e # do not stop or errors anyway
177+
178+ local _rc=$1 # Getting the exit code for a logging purpose only
179+ shift
135180
136181 say " Exiting on the $( ns_long $ns ) ($_rc ): $@ "
137182
@@ -142,9 +187,10 @@ hook_sub_exit() {
142187 warn " - terminating main <$MAINPID >"
143188 kill -TERM $MAINPID & > /dev/null
144189 fi
145- else
146- return $_rc
147190 fi
191+ # To prevent invoking error trap from error trap ;)
192+ # The correct exit code was taken before diving into this function
193+ return 0
148194}
149195
150196infinite_loop () {
0 commit comments