Skip to content

Commit 084396f

Browse files
author
Oleksii Tsvietnov
committed
Added a correct handling of exit-on-errors from sub commands
1 parent 40d251b commit 084396f

File tree

1 file changed

+63
-17
lines changed

1 file changed

+63
-17
lines changed

trc

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,38 +15,43 @@
1515
# - wait_forever will be waiting forever after exiting all commands.
1616
# Usefull in case of daemons which are detaching and exiting
1717

18-
1918
set +e # Do not exit on errors by default
2019
if [ "$RC_DEBUG" = "true" ]; then
2120
set -x # Turns on Debug mode if true
2221
fi
2322
: ${RC_WAIT_POLICY:=wait_any} # Sets default value for a wait policy
2423

2524
main() {
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

99138
say() {
@@ -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

133175
hook_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

150196
infinite_loop() {

0 commit comments

Comments
 (0)