0

I would like my shell script to fail, if a specific command fails. BUT in any case, run the entire script. So i thought about using return 1 at the end of the command i want to "catch" and maybe add a condition at the end like: if return 1; then exit 1. I'm a bit lost how this should look like.

#!/bin/bash

command 1 

# I want THIS command to make the script fail. 
# It runs test and in parallel regex
command 2 &

# bash regex that HAS to run in parallel with command 2
regex='^ID *\| *([0-9]+)'
while ! [[ $(command 3) =~ $regex ]] && jobs -rp | awk 'END{exit(NR==0)}'
do
    sleep 1
done

...

# Final command for creation of a report 
# Script has to run this command also if command 2 fails
command 4
t30_9
  • 347
  • 4
  • 17
  • If you consider a particular step to be failed, store an exit code into a variable. In the end of the script, just "return" this exit code (i.e. `exit $exitcode`). If you aassign different exit codes to the individual failure point, the caller can even understand, at which point in your script the error occurs. – user1934428 Dec 13 '22 at 09:06
  • 2
    You have to wait for `command 2` to complete before you know if it fails. Perhaps you just want to use `wait` to block your script until it completes, before running `command 4`? – chepner Dec 13 '22 at 13:51
  • 1
    If there are multiple background processes, one `wait` will pause till all are done, but it doesn't return an error if any fail. For that you need a `wait $pid` per process. See below. – Paul Hodges Dec 13 '22 at 18:01
  • 1
    Note that job control is an interactive extension; it's not available in scripts by default, and you don't _need_ it in the first place: `$!`, `wait`, &c all work fine without it. When writing a script, pretend `jobs` doesn't exist. – Charles Duffy Dec 13 '22 at 18:12
  • 1
    BTW, `command` is the name of a specific command that's POSIX-specified and built into the shell. Consider using `mycommand` or `somecommand` or otherwise an obviously-different placeholder to avoid unnecessary confusion. – Charles Duffy Dec 13 '22 at 18:13

1 Answers1

0

trap is your friend, but you have to be careful of those background tasks.

$: cat tst
#!/bin/bash
trap 'let err++' ERR
{ trap 'let err++' ERR; sleep 1; false; } & pid=$!
for str in foo bar baz ;do echo $str; done
wait $pid
echo happily done
exit $err

$: ./tst && echo ok || echo no
foo
bar
baz
happily done
no

Just make sure you test all your logic.

Paul Hodges
  • 13,382
  • 1
  • 17
  • 36