Reputation: 152
I'm writing a script that parses Bundler's output for errors, but I've run into an issue that I'm not certain how to handle:
response="$(bundle install 2>&1)"
echo $response
If Bundler fails, then $response is blank, and I can't parse it as I need. I've tried:
response="$(bundle install 2>&1 || true)"
echo $response
Which works, but isn't what I want because I still want my script to fail when Bundler fails.
How can I allow bundle install
to fail and still read its output?
I should also add that I'm using set -e
, which I need.
Edit:
After reading PSkocik's answer, this allows me to continue through the error, while still exiting when it happens:
response="$(bundle install 2>&1)" || bundle_status=$?
# Continue working (In my case, I'm parsing the errors to give more
# meaningful output for the context in which bundler is being run).
# And now I can exit with the given status code, or default to 0.
exit ${bundle_status:-0}
Upvotes: 5
Views: 3745
Reputation: 60068
It's because of the -e
option.
You need to make sure the error return status gets tested for:
man sh
on -e
(man bash
is a little more verbose on this, but in the same spirit)
If not interactive, exit immediately if any untested command fails. The exit status of a command is considered to be explicitly tested if the command is used to control an if, elif, while, or until; or if the command is the left hand operand of an “&&” or “||” operator.
Here's an example with a bundler mock (in sh, but should work in bash too):
#!/bin/sh
set -e
bundle(){
echo "i'm errorring here" >&2
return 32
}
response="$(bundle 2>&1)"
echo "won't get here if -e is set"
You can solve it like this:
response="$(bundle 2>&1)" || ret=$? #`set -e` won't kill us now
echo "will get here now"
echo "the bundle command exited with $ret"
echo "the response is ${response}"
If you need to echo strings that aren't yours, you should consider printf instead of echo (and don't forget double quotes): https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo
Upvotes: 4
Reputation: 531205
The problem is, you don't want your script to fail when Bundler does. You just want to exit after you've caught the error and done something with the error message. Don't use set -e
.
if ! response=$(bundle install 2>&1); then
ret=$?
# do something with $reponse
exit $ret
fi
Upvotes: 0
Reputation: 264
One option is to get rid of -e
and find a way to do more sophisticated error handling.
The other option is to replace the bundle command with a wrapper. Example:
function my-bundle {
set +e
output=$(bundle "$@" 2>&1)
ret=$?
echo "$output" # Add code for output parsing here
set -e
return $ret
}
# main script
set -e
There is no way you can have set -e
handle the return status of a command and run code after the command. (Unless you want to use trap
)
Upvotes: 1