Bash – How to print and exit bash if a backtick operator fails

bash

I have getinfo.sh which either prints information or exists with code 1.

I want to store the result of this script in a bash variable, otherwise print an error message and exit.

If I run this

#!/bin/bash
X=`getinfo.sh` || echo "failed" && exit 1

then the script exits even when getinfo.sh succeeds (in this case it prints nothing.

On the other hand

X=`getinfo.sh` || (echo "failed" && exit 1)

which makes sense to me, coming from C-like languages, but this does not exit the script since the parentheses create a new, inner shell, and it is the inner-shell which is exited, the outer shell keeps running.

How can I store the output of getinfo.sh and print-and-exit if that fails?

Best Answer

(...) is not (primarily) to group commands, but to start a subshell. So the exit in (echo failed && exit 1) only exits the subshell.

To group commands without running them in a subshell, you'd use { ...; } instead:

X=`getinfo.sh` || {
  echo >&2 "failed"
  exit 1
}

Though here, I'd rather use:

if ! x=$(getinfo.sh); then
  echo >&2 failed
  exit 1
fi

Also note that your echo failed && exit 1 could fail to exit if echo itself fails which could happen for intance when stdout is a file on a full filesystem, or a broken pipe with SIGPIPE ignored, or stdout has been closed, or a file size limit has been reached with SIGXFSZ ignored...