There are a couple of issues here:
- Getting the whole script to abort if a command in a subshell fails.
- Raising the visibility of any errors that occur.
I’ll start with the second one.
The question contains the seed of the answer: errors are logged,
but the content of the logs is not obvious to the user.
So log the errors (in an ad-hoc log file) and display them at the end:
services=(
account-service
reminder-service
activity-service
socket-service
chat-service
web-app
)
errfile=$(mktemp)
for s in "${services[@]}"; do
(
set -e;
cd "$s"
git pull || {
echo "$s" >> "$errfile"
exit 1
}
echo "$cmd" | bash
) &
sleep 1
done
wait
if [ -s "$errfile" ]
then
echo "The following service(s) had errors:"
cat "$errfile"
fi
rm -f "$errfile"
The simplest way to address issue #1
is to have the code in the subshell(s) check [ -s "$errfile" ]
periodically,
and abort itself if any problem arises.
A more ambitious approach would be
to have the main (parent) process keep track of the PIDs of the children
and send them signals.
I’m not sure how you would do that without wait -n
.
(Maybe you could have a child that has an error send a signal to the parent
to break it out of the wait
.)
echo "$cmd" | bash
instead ofbash -c "$cmd"
? For that matter, what is$cmd
? Is it so exotic and/or dynamic that you can’t just write it as a command (possibly with variable(s) as arguments)?eval $cmd
,bash -c "$cmd"
andecho "$cmd" | bash
all behave slightly differently?