3

Let's consider the following code:

a && b && c && d
echo "Command {xyz} ended with exit code $?"

If everything goes well, it's straightforward, as all the commands return exit code of 0. But if a non-zero exit code is encountered, is it possible to say, which command returned it and broke the chain - ie. what should be in {xyz}?

PS. I know that I could use nested conditional statements instead, but the chaining construct is pretty clear and understandable - I'd only like to add a bit of analysis to it.

Jasio
  • 275
  • 1
  • 7
  • 2
    I suggest to write a function (e.g. foo) and then use: `foo a && foo b && foo c && foo d` – Cyrus Jun 17 '18 at 11:01
  • @Cyrus If the commands needs to print an output in stdout, that'd be a little bit more complicated :p – Idriss Neumann Jun 17 '18 at 12:44
  • @IdrissNeumann. No it wouldn't – Mad Physicist Jun 17 '18 at 13:55
  • @MadPhysicist By "a little bit more complicated", I meant if you need to summarize the status of each part in a single `echo` for example and not mixing in the same function the outputs of the commands and customs status messages (that's seems to me not very clean). – Idriss Neumann Jun 17 '18 at 14:50
  • @Cyrus, thank you for reminding me. I have already managed to vote in the meantime. I also wanted to to give respondents a chance for more responces prior to deciding which one suits me best. – Jasio Jun 18 '18 at 19:52
  • Also see [How to use Shellcheck](https://github.com/koalaman/shellcheck), [How to debug a bash script?](https://unix.stackexchange.com/q/155551/56041) (U&L.SE), [How to debug a bash script?](https://stackoverflow.com/q/951336/608639) (SO), [How to debug bash script?](https://askubuntu.com/q/21136) (AskU), [Debugging Bash scripts](http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html), etc. – jww Jul 01 '18 at 00:10

2 Answers2

4

You could try something like :

{ a; status1=$?; } && { b; status2=$?; }
echo "status1=${status1}, status2=${status2}"

If you don't need to print the output in stdout of your commands, you might consider something like this :

run_and_check() {
    eval "$@" >/dev/null 2>&1 # you could replace /dev/null by a log file
    echo $?
}

status1=$(run_and_check "a") && status2=$(run_and_check "b")
echo "status1=${status1}, status2=${status2}"

But we don't save much compared to the first solution which is more generic and a lot less dangerous ;)

Idriss Neumann
  • 3,760
  • 2
  • 23
  • 32
2

With a function:

#!/bin/bash    

run() {
  $@ || echo "Command $1 ended with exit code $?"
}

run a && run b && run c && run d
Cyrus
  • 84,225
  • 14
  • 89
  • 153