proper way to detect shell exit code when errexit option setHow to override “set -e” in a script on specific command, but still get command exit codeHow to extract bits from return code number in BashExit Shell Script Based on Process Exit CodeWhat's a concise way to check that environment variables are set in a Unix shell script?How to store standard error in a variableShell Script Exit Code - Unable to setPiping command output to tee but also save exit code of commandIgnoring specific errors in a shell scriptUsing the RUN instruction in a Dockerfile with 'source' does not workChanging from tcsh to bash?Automatic exit from bash shell script on error: set +e does not seem to do the jobApplication's exit status is different than when application run by shell script
Does a druid starting with a bow start with no arrows?
Why is consensus so controversial in Britain?
How to model explosives?
Why are electrically insulating heatsinks so rare? Is it just cost?
Why does Kotter return in Welcome Back Kotter
Today is the Center
Fully-Firstable Anagram Sets
Can I make "comment-region" comment empty lines?
Why do I get two different answers for this counting problem?
What reasons are there for a Capitalist to oppose a 100% inheritance tax?
Has there ever been an airliner design involving reducing generator load by installing solar panels?
Watching something be written to a file live with tail
Doing something right before you need it - expression for this?
Why does Arabsat 6A need a Falcon Heavy to launch
Is "remove commented out code" correct English?
What is going on with Captain Marvel's blood colour?
1960's book about a plague that kills all white people
Is the Joker left-handed?
Forgetting the musical notes while performing in concert
Is it legal for company to use my work email to pretend I still work there?
Can I ask the recruiters in my resume to put the reason why I am rejected?
What to put in ESTA if staying in US for a few days before going on to Canada
What exploit are these user agents trying to use?
What is the intuition behind short exact sequences of groups; in particular, what is the intuition behind group extensions?
proper way to detect shell exit code when errexit option set
How to override “set -e” in a script on specific command, but still get command exit codeHow to extract bits from return code number in BashExit Shell Script Based on Process Exit CodeWhat's a concise way to check that environment variables are set in a Unix shell script?How to store standard error in a variableShell Script Exit Code - Unable to setPiping command output to tee but also save exit code of commandIgnoring specific errors in a shell scriptUsing the RUN instruction in a Dockerfile with 'source' does not workChanging from tcsh to bash?Automatic exit from bash shell script on error: set +e does not seem to do the jobApplication's exit status is different than when application run by shell script
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I prefer to write solid shell code, so the errexit & nounset is alway set.
The following code will stop at bad_command line
#!/bin/bash
set -o errexit ; set -o nounset
bad_command # stop here
good_command
I want to capture it, here is my method
#!/bin/bash
set -o errexit ; set -o nounset
rc=1
bad_command && rc=0 # stop here
[ $rc -ne 0 ] && do_err_handle
good_command
Is there any better or cleaner method
My Answer:
#!/bin/bash
set -o errexit ; set -o nounset
if ! bad_command ; then
# error handle here
fi
good_command
shell
add a comment |
I prefer to write solid shell code, so the errexit & nounset is alway set.
The following code will stop at bad_command line
#!/bin/bash
set -o errexit ; set -o nounset
bad_command # stop here
good_command
I want to capture it, here is my method
#!/bin/bash
set -o errexit ; set -o nounset
rc=1
bad_command && rc=0 # stop here
[ $rc -ne 0 ] && do_err_handle
good_command
Is there any better or cleaner method
My Answer:
#!/bin/bash
set -o errexit ; set -o nounset
if ! bad_command ; then
# error handle here
fi
good_command
shell
3
Don't seterrexitif you want to handle errors. Handle errors if you want to handle errors. Settingerrexitis abdicating from your responsibility to handle errors properly. I've never found it necessary to usenounset, but I am reasonably good at spelling consistently.
– Jonathan Leffler
Mar 9 '12 at 6:28
21
Always use errexit even if you want to handle errors. Any external command can fail and unless you plan on adding error handling for each|command|in|a&&work||flow then errexit will at least help protect you and the user. Same with nounset, not using it is like not using assert in other languages (because I never make errors, ever...)
– Paul Hargreaves
Sep 12 '12 at 20:54
FYI, none of these catch the full range of errexit codes. If yourbad_commandinternally calls another command, e.g.bad_com2, then errexit would crash the entire program. However, the checks listed here would miss the exit code ofbad_com2as long as it doesn't affect the exit code ofbad_command. Given that you're asking this question, you're probably well aware of this limitation, but others might think that these methods are a replacement for errexit :-)
– Hamy
Jun 18 '14 at 6:54
My above comment shows a bad situation too - you can't have a 'test' for "will errexit causing a failure" - your only option is to enable it and see.
– Hamy
Jun 18 '14 at 6:56
1
@Daniel In your answer, you don't need backticks aroundbad_command. I.e.,if ! bad_command; then ... fiis enough.
– Linus Arver
Sep 14 '16 at 20:10
add a comment |
I prefer to write solid shell code, so the errexit & nounset is alway set.
The following code will stop at bad_command line
#!/bin/bash
set -o errexit ; set -o nounset
bad_command # stop here
good_command
I want to capture it, here is my method
#!/bin/bash
set -o errexit ; set -o nounset
rc=1
bad_command && rc=0 # stop here
[ $rc -ne 0 ] && do_err_handle
good_command
Is there any better or cleaner method
My Answer:
#!/bin/bash
set -o errexit ; set -o nounset
if ! bad_command ; then
# error handle here
fi
good_command
shell
I prefer to write solid shell code, so the errexit & nounset is alway set.
The following code will stop at bad_command line
#!/bin/bash
set -o errexit ; set -o nounset
bad_command # stop here
good_command
I want to capture it, here is my method
#!/bin/bash
set -o errexit ; set -o nounset
rc=1
bad_command && rc=0 # stop here
[ $rc -ne 0 ] && do_err_handle
good_command
Is there any better or cleaner method
My Answer:
#!/bin/bash
set -o errexit ; set -o nounset
if ! bad_command ; then
# error handle here
fi
good_command
shell
shell
edited Jan 10 '17 at 8:07
Daniel YC Lin
asked Mar 9 '12 at 6:10
Daniel YC LinDaniel YC Lin
4,85894166
4,85894166
3
Don't seterrexitif you want to handle errors. Handle errors if you want to handle errors. Settingerrexitis abdicating from your responsibility to handle errors properly. I've never found it necessary to usenounset, but I am reasonably good at spelling consistently.
– Jonathan Leffler
Mar 9 '12 at 6:28
21
Always use errexit even if you want to handle errors. Any external command can fail and unless you plan on adding error handling for each|command|in|a&&work||flow then errexit will at least help protect you and the user. Same with nounset, not using it is like not using assert in other languages (because I never make errors, ever...)
– Paul Hargreaves
Sep 12 '12 at 20:54
FYI, none of these catch the full range of errexit codes. If yourbad_commandinternally calls another command, e.g.bad_com2, then errexit would crash the entire program. However, the checks listed here would miss the exit code ofbad_com2as long as it doesn't affect the exit code ofbad_command. Given that you're asking this question, you're probably well aware of this limitation, but others might think that these methods are a replacement for errexit :-)
– Hamy
Jun 18 '14 at 6:54
My above comment shows a bad situation too - you can't have a 'test' for "will errexit causing a failure" - your only option is to enable it and see.
– Hamy
Jun 18 '14 at 6:56
1
@Daniel In your answer, you don't need backticks aroundbad_command. I.e.,if ! bad_command; then ... fiis enough.
– Linus Arver
Sep 14 '16 at 20:10
add a comment |
3
Don't seterrexitif you want to handle errors. Handle errors if you want to handle errors. Settingerrexitis abdicating from your responsibility to handle errors properly. I've never found it necessary to usenounset, but I am reasonably good at spelling consistently.
– Jonathan Leffler
Mar 9 '12 at 6:28
21
Always use errexit even if you want to handle errors. Any external command can fail and unless you plan on adding error handling for each|command|in|a&&work||flow then errexit will at least help protect you and the user. Same with nounset, not using it is like not using assert in other languages (because I never make errors, ever...)
– Paul Hargreaves
Sep 12 '12 at 20:54
FYI, none of these catch the full range of errexit codes. If yourbad_commandinternally calls another command, e.g.bad_com2, then errexit would crash the entire program. However, the checks listed here would miss the exit code ofbad_com2as long as it doesn't affect the exit code ofbad_command. Given that you're asking this question, you're probably well aware of this limitation, but others might think that these methods are a replacement for errexit :-)
– Hamy
Jun 18 '14 at 6:54
My above comment shows a bad situation too - you can't have a 'test' for "will errexit causing a failure" - your only option is to enable it and see.
– Hamy
Jun 18 '14 at 6:56
1
@Daniel In your answer, you don't need backticks aroundbad_command. I.e.,if ! bad_command; then ... fiis enough.
– Linus Arver
Sep 14 '16 at 20:10
3
3
Don't set
errexit if you want to handle errors. Handle errors if you want to handle errors. Setting errexit is abdicating from your responsibility to handle errors properly. I've never found it necessary to use nounset, but I am reasonably good at spelling consistently.– Jonathan Leffler
Mar 9 '12 at 6:28
Don't set
errexit if you want to handle errors. Handle errors if you want to handle errors. Setting errexit is abdicating from your responsibility to handle errors properly. I've never found it necessary to use nounset, but I am reasonably good at spelling consistently.– Jonathan Leffler
Mar 9 '12 at 6:28
21
21
Always use errexit even if you want to handle errors. Any external command can fail and unless you plan on adding error handling for each|command|in|a&&work||flow then errexit will at least help protect you and the user. Same with nounset, not using it is like not using assert in other languages (because I never make errors, ever...)
– Paul Hargreaves
Sep 12 '12 at 20:54
Always use errexit even if you want to handle errors. Any external command can fail and unless you plan on adding error handling for each|command|in|a&&work||flow then errexit will at least help protect you and the user. Same with nounset, not using it is like not using assert in other languages (because I never make errors, ever...)
– Paul Hargreaves
Sep 12 '12 at 20:54
FYI, none of these catch the full range of errexit codes. If your
bad_command internally calls another command, e.g. bad_com2, then errexit would crash the entire program. However, the checks listed here would miss the exit code of bad_com2 as long as it doesn't affect the exit code of bad_command. Given that you're asking this question, you're probably well aware of this limitation, but others might think that these methods are a replacement for errexit :-)– Hamy
Jun 18 '14 at 6:54
FYI, none of these catch the full range of errexit codes. If your
bad_command internally calls another command, e.g. bad_com2, then errexit would crash the entire program. However, the checks listed here would miss the exit code of bad_com2 as long as it doesn't affect the exit code of bad_command. Given that you're asking this question, you're probably well aware of this limitation, but others might think that these methods are a replacement for errexit :-)– Hamy
Jun 18 '14 at 6:54
My above comment shows a bad situation too - you can't have a 'test' for "will errexit causing a failure" - your only option is to enable it and see.
– Hamy
Jun 18 '14 at 6:56
My above comment shows a bad situation too - you can't have a 'test' for "will errexit causing a failure" - your only option is to enable it and see.
– Hamy
Jun 18 '14 at 6:56
1
1
@Daniel In your answer, you don't need backticks around
bad_command. I.e., if ! bad_command; then ... fi is enough.– Linus Arver
Sep 14 '16 at 20:10
@Daniel In your answer, you don't need backticks around
bad_command. I.e., if ! bad_command; then ... fi is enough.– Linus Arver
Sep 14 '16 at 20:10
add a comment |
12 Answers
12
active
oldest
votes
How about this? If you want the actual exit code ...
#!/bin/sh
set -e
cat /tmp/doesnotexist && rc=$? || rc=$?
echo exitcode: $rc
cat /dev/null && rc=$? || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
2
I like this method, it is lean.
– Daniel YC Lin
Apr 6 '13 at 23:17
why does this work? Does shell interpret this as( command && rc=$? ) || rc=$??
– Michel Müller
Apr 14 '16 at 11:21
1
See unix.stackexchange.com/questions/88850/…
– rrauenza
Apr 14 '16 at 15:27
2
@MichelMüller it works because the whole statement works together and the final err code is 0, so errexit doesn't exit. Yes, your interpretation, with parentheses, appears correct. In fact, you can test this: Try thisls fakefile && x=1 || x=2 ; echo $x
– JDS
Apr 21 '16 at 13:41
I find having&&and||in the same line somehow unintuitive. Another way is to first definerc=0and only setrcto the actual exit code if the command failed:rc=0; cat /tmp/doesnotexist || rc=$?. This works because the piece of code after your&&will always setrcto zero so you could as well modify your own code to say... && rc=0 || ...
– josch
Oct 20 '18 at 18:41
add a comment |
Keep with errexit. It can help find bugs that otherwise might have unpredictable (and hard to detect) results.
#!/bin/bash
set -o errexit ; set -o nounset
bad_command || do_err_handle
good_command
The above will work fine. errexit only requires that the line pass, as you do with the bad_command && rc=0. Therefore, the above with the 'or' will only run do_err_handle if bad_command fails and, as long as do_err_handle doesn't also 'fail', then the script will continue.
4
This is the correct way of doing it. To expand further, bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:58
this is so useful it blows my mind.....
– gloomy.penguin
Dec 5 '14 at 20:59
add a comment |
set -o errexit
bad_command ||
resp_code=$?
echo Bad Thing $resp_code happened
add a comment |
A common way to avoid exiting a Bash program when errexit is set and a command that may fail is run is to precede the command with !.
After the command has run $? does not contain the exit status of the command. (It contains 0 if the command failed and 1 otherwise.) However, the PIPESTATUS array does contain the exit status of the command. A safe way to capture the exit status of a command that may fail, whether or not errexit is set, is:
! bad_command
rc=$PIPESTATUS[0]
The second line can be simplified to rc=$PIPESTATUS, but Shellcheck will complain about it.
If (as is often the case) you don't need to know the exit status of the command, just if it succeeded or failed, then the solution by @george is good if the error handler is a one-liner. For multi-line error handlers a good option is:
if ! bad_command ; then
# Handle errors here
fi
Note that (except in very unusual circumstances) it would not be correct to use `bad_command` (as suggested in the question) instead of plain bad_command. You can use $PIPESTATUS[0] to get the exit status of the command if it is needed in the error handling code, since $? doesn't contain it in this case either.
add a comment |
Agree with comments, so if you can give up errexit then you can easily shorten your code to
bad_command || do_err_handle
good_command
I hope this helps.
thanks, I don't want to give up errexit. You give me good hint.
– Daniel YC Lin
Mar 16 '12 at 1:19
3
To expand on this: bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:49
add a comment |
Continue to write solid shell code.
You do it right if bad_command is really a command.
But be careful with function calls in if, while, ||, && or !, because errexit will not work there. It may be dangerous.
If your bad_command is actually bad_function you should write this:
set -eu
get_exit_code()
set +e
( set -e;
"$@"
)
exit_code=$?
set -e
...
get_exit_code bad_function
if [ "$exit_code" != 0 ]; then
do_err_handle
fi
This works well in bash 4.0. In bash 4.2 you only get exit codes 0 or 1.
add a comment |
what if you want to know exit status of bad_command?
I think the simplest way is to disable errexit:
#!/bin/sh
set -o errexit
some_code_here
set +o errexit
bad_command
status=$?
set -o errexit
process $status
5
This technique is ok if you only have to catch one command, but if you want to correctly handle lots of commands that may return codes (like grep, diff etc) then it'll prove painful.
– Paul Hargreaves
Sep 12 '12 at 20:51
@PaulHargreaves but this seems really the only way to get the error code of the command. Probably needed, but useful in some cases.
– vadipp
Feb 8 '13 at 3:43
add a comment |
In bash you can use the trap builtin which is quite nice. See
https://unix.stackexchange.com/questions/79648/how-to-trigger-error-using-trap-command
Not sure how portable it is with other shells.. so YMMV
add a comment |
I cobbled together a (hopefully) textbook example from all the answers:
#!/usr/bin/env bash
# exit immediately on error
set -o errexit
file='dfkjlfdlkj'
# Turn off 'exit immediately on error' during the command substitution
blah=$(set +o errexit && ls $file) && rc=$? || rc=$?
echo $blah
# Do something special if $rc
(( $rc )) && echo failure && exit 1
echo success
add a comment |
A slight variation of the answer given by @rrauenza. Since the && rc=$? part is their answer will always be equal to && rc=0 one can as well set rc to 0 before running the command. The result ends up more readable in my opinion because the variable is defined upfront in its own line of code and is only changed if the command exits with a non-zero exit status. If nounset is also given, then it's now clear that rc was indeed never undefined. This also avoids mixing && and || in the same line which might be confusing because one might not always know the operator precedence by heart.
#!/bin/sh
set -eu
rc=0
cat /tmp/doesnotexist || rc=$?
echo exitcode: $rc
rc=0
cat /dev/null || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
add a comment |
A clean reliable way to error exit
command_that_error_exits || echo "Line $LINENO: Failed with Error" 1>&2; exit 1;
add a comment |
The accepted answer is good, but I think it could be refactored to be even better; more generic, easier to refactor and read:
some_command_status=$(some_command && echo $? || echo $?)
vs.
some_command && some_command_status=$? || some_command_status=$?
1
Note that using$(some_command ...)may create an extra subprocess (particularly in Bash) and cause performance problems. Also, there are rare circumstances where a command will behave significantly differently if run in a subprocess.
– pjh
Dec 13 '16 at 20:13
1
This won't work ifsome_commandproduces output.
– pjh
Dec 14 '16 at 11:07
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9629710%2fproper-way-to-detect-shell-exit-code-when-errexit-option-set%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
12 Answers
12
active
oldest
votes
12 Answers
12
active
oldest
votes
active
oldest
votes
active
oldest
votes
How about this? If you want the actual exit code ...
#!/bin/sh
set -e
cat /tmp/doesnotexist && rc=$? || rc=$?
echo exitcode: $rc
cat /dev/null && rc=$? || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
2
I like this method, it is lean.
– Daniel YC Lin
Apr 6 '13 at 23:17
why does this work? Does shell interpret this as( command && rc=$? ) || rc=$??
– Michel Müller
Apr 14 '16 at 11:21
1
See unix.stackexchange.com/questions/88850/…
– rrauenza
Apr 14 '16 at 15:27
2
@MichelMüller it works because the whole statement works together and the final err code is 0, so errexit doesn't exit. Yes, your interpretation, with parentheses, appears correct. In fact, you can test this: Try thisls fakefile && x=1 || x=2 ; echo $x
– JDS
Apr 21 '16 at 13:41
I find having&&and||in the same line somehow unintuitive. Another way is to first definerc=0and only setrcto the actual exit code if the command failed:rc=0; cat /tmp/doesnotexist || rc=$?. This works because the piece of code after your&&will always setrcto zero so you could as well modify your own code to say... && rc=0 || ...
– josch
Oct 20 '18 at 18:41
add a comment |
How about this? If you want the actual exit code ...
#!/bin/sh
set -e
cat /tmp/doesnotexist && rc=$? || rc=$?
echo exitcode: $rc
cat /dev/null && rc=$? || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
2
I like this method, it is lean.
– Daniel YC Lin
Apr 6 '13 at 23:17
why does this work? Does shell interpret this as( command && rc=$? ) || rc=$??
– Michel Müller
Apr 14 '16 at 11:21
1
See unix.stackexchange.com/questions/88850/…
– rrauenza
Apr 14 '16 at 15:27
2
@MichelMüller it works because the whole statement works together and the final err code is 0, so errexit doesn't exit. Yes, your interpretation, with parentheses, appears correct. In fact, you can test this: Try thisls fakefile && x=1 || x=2 ; echo $x
– JDS
Apr 21 '16 at 13:41
I find having&&and||in the same line somehow unintuitive. Another way is to first definerc=0and only setrcto the actual exit code if the command failed:rc=0; cat /tmp/doesnotexist || rc=$?. This works because the piece of code after your&&will always setrcto zero so you could as well modify your own code to say... && rc=0 || ...
– josch
Oct 20 '18 at 18:41
add a comment |
How about this? If you want the actual exit code ...
#!/bin/sh
set -e
cat /tmp/doesnotexist && rc=$? || rc=$?
echo exitcode: $rc
cat /dev/null && rc=$? || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
How about this? If you want the actual exit code ...
#!/bin/sh
set -e
cat /tmp/doesnotexist && rc=$? || rc=$?
echo exitcode: $rc
cat /dev/null && rc=$? || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
edited Oct 17 '14 at 16:46
answered Apr 5 '13 at 22:51
rrauenzarrauenza
3,55921835
3,55921835
2
I like this method, it is lean.
– Daniel YC Lin
Apr 6 '13 at 23:17
why does this work? Does shell interpret this as( command && rc=$? ) || rc=$??
– Michel Müller
Apr 14 '16 at 11:21
1
See unix.stackexchange.com/questions/88850/…
– rrauenza
Apr 14 '16 at 15:27
2
@MichelMüller it works because the whole statement works together and the final err code is 0, so errexit doesn't exit. Yes, your interpretation, with parentheses, appears correct. In fact, you can test this: Try thisls fakefile && x=1 || x=2 ; echo $x
– JDS
Apr 21 '16 at 13:41
I find having&&and||in the same line somehow unintuitive. Another way is to first definerc=0and only setrcto the actual exit code if the command failed:rc=0; cat /tmp/doesnotexist || rc=$?. This works because the piece of code after your&&will always setrcto zero so you could as well modify your own code to say... && rc=0 || ...
– josch
Oct 20 '18 at 18:41
add a comment |
2
I like this method, it is lean.
– Daniel YC Lin
Apr 6 '13 at 23:17
why does this work? Does shell interpret this as( command && rc=$? ) || rc=$??
– Michel Müller
Apr 14 '16 at 11:21
1
See unix.stackexchange.com/questions/88850/…
– rrauenza
Apr 14 '16 at 15:27
2
@MichelMüller it works because the whole statement works together and the final err code is 0, so errexit doesn't exit. Yes, your interpretation, with parentheses, appears correct. In fact, you can test this: Try thisls fakefile && x=1 || x=2 ; echo $x
– JDS
Apr 21 '16 at 13:41
I find having&&and||in the same line somehow unintuitive. Another way is to first definerc=0and only setrcto the actual exit code if the command failed:rc=0; cat /tmp/doesnotexist || rc=$?. This works because the piece of code after your&&will always setrcto zero so you could as well modify your own code to say... && rc=0 || ...
– josch
Oct 20 '18 at 18:41
2
2
I like this method, it is lean.
– Daniel YC Lin
Apr 6 '13 at 23:17
I like this method, it is lean.
– Daniel YC Lin
Apr 6 '13 at 23:17
why does this work? Does shell interpret this as
( command && rc=$? ) || rc=$? ?– Michel Müller
Apr 14 '16 at 11:21
why does this work? Does shell interpret this as
( command && rc=$? ) || rc=$? ?– Michel Müller
Apr 14 '16 at 11:21
1
1
See unix.stackexchange.com/questions/88850/…
– rrauenza
Apr 14 '16 at 15:27
See unix.stackexchange.com/questions/88850/…
– rrauenza
Apr 14 '16 at 15:27
2
2
@MichelMüller it works because the whole statement works together and the final err code is 0, so errexit doesn't exit. Yes, your interpretation, with parentheses, appears correct. In fact, you can test this: Try this
ls fakefile && x=1 || x=2 ; echo $x– JDS
Apr 21 '16 at 13:41
@MichelMüller it works because the whole statement works together and the final err code is 0, so errexit doesn't exit. Yes, your interpretation, with parentheses, appears correct. In fact, you can test this: Try this
ls fakefile && x=1 || x=2 ; echo $x– JDS
Apr 21 '16 at 13:41
I find having
&& and || in the same line somehow unintuitive. Another way is to first define rc=0 and only set rc to the actual exit code if the command failed: rc=0; cat /tmp/doesnotexist || rc=$?. This works because the piece of code after your && will always set rc to zero so you could as well modify your own code to say ... && rc=0 || ...– josch
Oct 20 '18 at 18:41
I find having
&& and || in the same line somehow unintuitive. Another way is to first define rc=0 and only set rc to the actual exit code if the command failed: rc=0; cat /tmp/doesnotexist || rc=$?. This works because the piece of code after your && will always set rc to zero so you could as well modify your own code to say ... && rc=0 || ...– josch
Oct 20 '18 at 18:41
add a comment |
Keep with errexit. It can help find bugs that otherwise might have unpredictable (and hard to detect) results.
#!/bin/bash
set -o errexit ; set -o nounset
bad_command || do_err_handle
good_command
The above will work fine. errexit only requires that the line pass, as you do with the bad_command && rc=0. Therefore, the above with the 'or' will only run do_err_handle if bad_command fails and, as long as do_err_handle doesn't also 'fail', then the script will continue.
4
This is the correct way of doing it. To expand further, bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:58
this is so useful it blows my mind.....
– gloomy.penguin
Dec 5 '14 at 20:59
add a comment |
Keep with errexit. It can help find bugs that otherwise might have unpredictable (and hard to detect) results.
#!/bin/bash
set -o errexit ; set -o nounset
bad_command || do_err_handle
good_command
The above will work fine. errexit only requires that the line pass, as you do with the bad_command && rc=0. Therefore, the above with the 'or' will only run do_err_handle if bad_command fails and, as long as do_err_handle doesn't also 'fail', then the script will continue.
4
This is the correct way of doing it. To expand further, bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:58
this is so useful it blows my mind.....
– gloomy.penguin
Dec 5 '14 at 20:59
add a comment |
Keep with errexit. It can help find bugs that otherwise might have unpredictable (and hard to detect) results.
#!/bin/bash
set -o errexit ; set -o nounset
bad_command || do_err_handle
good_command
The above will work fine. errexit only requires that the line pass, as you do with the bad_command && rc=0. Therefore, the above with the 'or' will only run do_err_handle if bad_command fails and, as long as do_err_handle doesn't also 'fail', then the script will continue.
Keep with errexit. It can help find bugs that otherwise might have unpredictable (and hard to detect) results.
#!/bin/bash
set -o errexit ; set -o nounset
bad_command || do_err_handle
good_command
The above will work fine. errexit only requires that the line pass, as you do with the bad_command && rc=0. Therefore, the above with the 'or' will only run do_err_handle if bad_command fails and, as long as do_err_handle doesn't also 'fail', then the script will continue.
edited Aug 30 '12 at 12:19
ЯegDwight
21.6k93849
21.6k93849
answered Aug 30 '12 at 12:07
georgegeorge
18112
18112
4
This is the correct way of doing it. To expand further, bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:58
this is so useful it blows my mind.....
– gloomy.penguin
Dec 5 '14 at 20:59
add a comment |
4
This is the correct way of doing it. To expand further, bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:58
this is so useful it blows my mind.....
– gloomy.penguin
Dec 5 '14 at 20:59
4
4
This is the correct way of doing it. To expand further, bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:58
This is the correct way of doing it. To expand further, bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:58
this is so useful it blows my mind.....
– gloomy.penguin
Dec 5 '14 at 20:59
this is so useful it blows my mind.....
– gloomy.penguin
Dec 5 '14 at 20:59
add a comment |
set -o errexit
bad_command ||
resp_code=$?
echo Bad Thing $resp_code happened
add a comment |
set -o errexit
bad_command ||
resp_code=$?
echo Bad Thing $resp_code happened
add a comment |
set -o errexit
bad_command ||
resp_code=$?
echo Bad Thing $resp_code happened
set -o errexit
bad_command ||
resp_code=$?
echo Bad Thing $resp_code happened
answered Mar 18 '14 at 15:07
user2870994user2870994
311
311
add a comment |
add a comment |
A common way to avoid exiting a Bash program when errexit is set and a command that may fail is run is to precede the command with !.
After the command has run $? does not contain the exit status of the command. (It contains 0 if the command failed and 1 otherwise.) However, the PIPESTATUS array does contain the exit status of the command. A safe way to capture the exit status of a command that may fail, whether or not errexit is set, is:
! bad_command
rc=$PIPESTATUS[0]
The second line can be simplified to rc=$PIPESTATUS, but Shellcheck will complain about it.
If (as is often the case) you don't need to know the exit status of the command, just if it succeeded or failed, then the solution by @george is good if the error handler is a one-liner. For multi-line error handlers a good option is:
if ! bad_command ; then
# Handle errors here
fi
Note that (except in very unusual circumstances) it would not be correct to use `bad_command` (as suggested in the question) instead of plain bad_command. You can use $PIPESTATUS[0] to get the exit status of the command if it is needed in the error handling code, since $? doesn't contain it in this case either.
add a comment |
A common way to avoid exiting a Bash program when errexit is set and a command that may fail is run is to precede the command with !.
After the command has run $? does not contain the exit status of the command. (It contains 0 if the command failed and 1 otherwise.) However, the PIPESTATUS array does contain the exit status of the command. A safe way to capture the exit status of a command that may fail, whether or not errexit is set, is:
! bad_command
rc=$PIPESTATUS[0]
The second line can be simplified to rc=$PIPESTATUS, but Shellcheck will complain about it.
If (as is often the case) you don't need to know the exit status of the command, just if it succeeded or failed, then the solution by @george is good if the error handler is a one-liner. For multi-line error handlers a good option is:
if ! bad_command ; then
# Handle errors here
fi
Note that (except in very unusual circumstances) it would not be correct to use `bad_command` (as suggested in the question) instead of plain bad_command. You can use $PIPESTATUS[0] to get the exit status of the command if it is needed in the error handling code, since $? doesn't contain it in this case either.
add a comment |
A common way to avoid exiting a Bash program when errexit is set and a command that may fail is run is to precede the command with !.
After the command has run $? does not contain the exit status of the command. (It contains 0 if the command failed and 1 otherwise.) However, the PIPESTATUS array does contain the exit status of the command. A safe way to capture the exit status of a command that may fail, whether or not errexit is set, is:
! bad_command
rc=$PIPESTATUS[0]
The second line can be simplified to rc=$PIPESTATUS, but Shellcheck will complain about it.
If (as is often the case) you don't need to know the exit status of the command, just if it succeeded or failed, then the solution by @george is good if the error handler is a one-liner. For multi-line error handlers a good option is:
if ! bad_command ; then
# Handle errors here
fi
Note that (except in very unusual circumstances) it would not be correct to use `bad_command` (as suggested in the question) instead of plain bad_command. You can use $PIPESTATUS[0] to get the exit status of the command if it is needed in the error handling code, since $? doesn't contain it in this case either.
A common way to avoid exiting a Bash program when errexit is set and a command that may fail is run is to precede the command with !.
After the command has run $? does not contain the exit status of the command. (It contains 0 if the command failed and 1 otherwise.) However, the PIPESTATUS array does contain the exit status of the command. A safe way to capture the exit status of a command that may fail, whether or not errexit is set, is:
! bad_command
rc=$PIPESTATUS[0]
The second line can be simplified to rc=$PIPESTATUS, but Shellcheck will complain about it.
If (as is often the case) you don't need to know the exit status of the command, just if it succeeded or failed, then the solution by @george is good if the error handler is a one-liner. For multi-line error handlers a good option is:
if ! bad_command ; then
# Handle errors here
fi
Note that (except in very unusual circumstances) it would not be correct to use `bad_command` (as suggested in the question) instead of plain bad_command. You can use $PIPESTATUS[0] to get the exit status of the command if it is needed in the error handling code, since $? doesn't contain it in this case either.
answered Dec 13 '16 at 19:43
pjhpjh
1,954713
1,954713
add a comment |
add a comment |
Agree with comments, so if you can give up errexit then you can easily shorten your code to
bad_command || do_err_handle
good_command
I hope this helps.
thanks, I don't want to give up errexit. You give me good hint.
– Daniel YC Lin
Mar 16 '12 at 1:19
3
To expand on this: bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:49
add a comment |
Agree with comments, so if you can give up errexit then you can easily shorten your code to
bad_command || do_err_handle
good_command
I hope this helps.
thanks, I don't want to give up errexit. You give me good hint.
– Daniel YC Lin
Mar 16 '12 at 1:19
3
To expand on this: bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:49
add a comment |
Agree with comments, so if you can give up errexit then you can easily shorten your code to
bad_command || do_err_handle
good_command
I hope this helps.
Agree with comments, so if you can give up errexit then you can easily shorten your code to
bad_command || do_err_handle
good_command
I hope this helps.
answered Mar 9 '12 at 14:48
shelltershellter
29.4k66075
29.4k66075
thanks, I don't want to give up errexit. You give me good hint.
– Daniel YC Lin
Mar 16 '12 at 1:19
3
To expand on this: bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:49
add a comment |
thanks, I don't want to give up errexit. You give me good hint.
– Daniel YC Lin
Mar 16 '12 at 1:19
3
To expand on this: bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:49
thanks, I don't want to give up errexit. You give me good hint.
– Daniel YC Lin
Mar 16 '12 at 1:19
thanks, I don't want to give up errexit. You give me good hint.
– Daniel YC Lin
Mar 16 '12 at 1:19
3
3
To expand on this: bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:49
To expand on this: bad_command || echo "My error message explaining why the crash"; exit 1
– Paul Hargreaves
Sep 12 '12 at 20:49
add a comment |
Continue to write solid shell code.
You do it right if bad_command is really a command.
But be careful with function calls in if, while, ||, && or !, because errexit will not work there. It may be dangerous.
If your bad_command is actually bad_function you should write this:
set -eu
get_exit_code()
set +e
( set -e;
"$@"
)
exit_code=$?
set -e
...
get_exit_code bad_function
if [ "$exit_code" != 0 ]; then
do_err_handle
fi
This works well in bash 4.0. In bash 4.2 you only get exit codes 0 or 1.
add a comment |
Continue to write solid shell code.
You do it right if bad_command is really a command.
But be careful with function calls in if, while, ||, && or !, because errexit will not work there. It may be dangerous.
If your bad_command is actually bad_function you should write this:
set -eu
get_exit_code()
set +e
( set -e;
"$@"
)
exit_code=$?
set -e
...
get_exit_code bad_function
if [ "$exit_code" != 0 ]; then
do_err_handle
fi
This works well in bash 4.0. In bash 4.2 you only get exit codes 0 or 1.
add a comment |
Continue to write solid shell code.
You do it right if bad_command is really a command.
But be careful with function calls in if, while, ||, && or !, because errexit will not work there. It may be dangerous.
If your bad_command is actually bad_function you should write this:
set -eu
get_exit_code()
set +e
( set -e;
"$@"
)
exit_code=$?
set -e
...
get_exit_code bad_function
if [ "$exit_code" != 0 ]; then
do_err_handle
fi
This works well in bash 4.0. In bash 4.2 you only get exit codes 0 or 1.
Continue to write solid shell code.
You do it right if bad_command is really a command.
But be careful with function calls in if, while, ||, && or !, because errexit will not work there. It may be dangerous.
If your bad_command is actually bad_function you should write this:
set -eu
get_exit_code()
set +e
( set -e;
"$@"
)
exit_code=$?
set -e
...
get_exit_code bad_function
if [ "$exit_code" != 0 ]; then
do_err_handle
fi
This works well in bash 4.0. In bash 4.2 you only get exit codes 0 or 1.
answered Aug 25 '15 at 10:37
yaroligyarolig
15315
15315
add a comment |
add a comment |
what if you want to know exit status of bad_command?
I think the simplest way is to disable errexit:
#!/bin/sh
set -o errexit
some_code_here
set +o errexit
bad_command
status=$?
set -o errexit
process $status
5
This technique is ok if you only have to catch one command, but if you want to correctly handle lots of commands that may return codes (like grep, diff etc) then it'll prove painful.
– Paul Hargreaves
Sep 12 '12 at 20:51
@PaulHargreaves but this seems really the only way to get the error code of the command. Probably needed, but useful in some cases.
– vadipp
Feb 8 '13 at 3:43
add a comment |
what if you want to know exit status of bad_command?
I think the simplest way is to disable errexit:
#!/bin/sh
set -o errexit
some_code_here
set +o errexit
bad_command
status=$?
set -o errexit
process $status
5
This technique is ok if you only have to catch one command, but if you want to correctly handle lots of commands that may return codes (like grep, diff etc) then it'll prove painful.
– Paul Hargreaves
Sep 12 '12 at 20:51
@PaulHargreaves but this seems really the only way to get the error code of the command. Probably needed, but useful in some cases.
– vadipp
Feb 8 '13 at 3:43
add a comment |
what if you want to know exit status of bad_command?
I think the simplest way is to disable errexit:
#!/bin/sh
set -o errexit
some_code_here
set +o errexit
bad_command
status=$?
set -o errexit
process $status
what if you want to know exit status of bad_command?
I think the simplest way is to disable errexit:
#!/bin/sh
set -o errexit
some_code_here
set +o errexit
bad_command
status=$?
set -o errexit
process $status
answered Sep 8 '12 at 17:07
Andrey KartashovAndrey Kartashov
11
11
5
This technique is ok if you only have to catch one command, but if you want to correctly handle lots of commands that may return codes (like grep, diff etc) then it'll prove painful.
– Paul Hargreaves
Sep 12 '12 at 20:51
@PaulHargreaves but this seems really the only way to get the error code of the command. Probably needed, but useful in some cases.
– vadipp
Feb 8 '13 at 3:43
add a comment |
5
This technique is ok if you only have to catch one command, but if you want to correctly handle lots of commands that may return codes (like grep, diff etc) then it'll prove painful.
– Paul Hargreaves
Sep 12 '12 at 20:51
@PaulHargreaves but this seems really the only way to get the error code of the command. Probably needed, but useful in some cases.
– vadipp
Feb 8 '13 at 3:43
5
5
This technique is ok if you only have to catch one command, but if you want to correctly handle lots of commands that may return codes (like grep, diff etc) then it'll prove painful.
– Paul Hargreaves
Sep 12 '12 at 20:51
This technique is ok if you only have to catch one command, but if you want to correctly handle lots of commands that may return codes (like grep, diff etc) then it'll prove painful.
– Paul Hargreaves
Sep 12 '12 at 20:51
@PaulHargreaves but this seems really the only way to get the error code of the command. Probably needed, but useful in some cases.
– vadipp
Feb 8 '13 at 3:43
@PaulHargreaves but this seems really the only way to get the error code of the command. Probably needed, but useful in some cases.
– vadipp
Feb 8 '13 at 3:43
add a comment |
In bash you can use the trap builtin which is quite nice. See
https://unix.stackexchange.com/questions/79648/how-to-trigger-error-using-trap-command
Not sure how portable it is with other shells.. so YMMV
add a comment |
In bash you can use the trap builtin which is quite nice. See
https://unix.stackexchange.com/questions/79648/how-to-trigger-error-using-trap-command
Not sure how portable it is with other shells.. so YMMV
add a comment |
In bash you can use the trap builtin which is quite nice. See
https://unix.stackexchange.com/questions/79648/how-to-trigger-error-using-trap-command
Not sure how portable it is with other shells.. so YMMV
In bash you can use the trap builtin which is quite nice. See
https://unix.stackexchange.com/questions/79648/how-to-trigger-error-using-trap-command
Not sure how portable it is with other shells.. so YMMV
edited Apr 13 '17 at 12:36
Community♦
11
11
answered Feb 4 '16 at 23:29
demented hedgehogdemented hedgehog
4,47412932
4,47412932
add a comment |
add a comment |
I cobbled together a (hopefully) textbook example from all the answers:
#!/usr/bin/env bash
# exit immediately on error
set -o errexit
file='dfkjlfdlkj'
# Turn off 'exit immediately on error' during the command substitution
blah=$(set +o errexit && ls $file) && rc=$? || rc=$?
echo $blah
# Do something special if $rc
(( $rc )) && echo failure && exit 1
echo success
add a comment |
I cobbled together a (hopefully) textbook example from all the answers:
#!/usr/bin/env bash
# exit immediately on error
set -o errexit
file='dfkjlfdlkj'
# Turn off 'exit immediately on error' during the command substitution
blah=$(set +o errexit && ls $file) && rc=$? || rc=$?
echo $blah
# Do something special if $rc
(( $rc )) && echo failure && exit 1
echo success
add a comment |
I cobbled together a (hopefully) textbook example from all the answers:
#!/usr/bin/env bash
# exit immediately on error
set -o errexit
file='dfkjlfdlkj'
# Turn off 'exit immediately on error' during the command substitution
blah=$(set +o errexit && ls $file) && rc=$? || rc=$?
echo $blah
# Do something special if $rc
(( $rc )) && echo failure && exit 1
echo success
I cobbled together a (hopefully) textbook example from all the answers:
#!/usr/bin/env bash
# exit immediately on error
set -o errexit
file='dfkjlfdlkj'
# Turn off 'exit immediately on error' during the command substitution
blah=$(set +o errexit && ls $file) && rc=$? || rc=$?
echo $blah
# Do something special if $rc
(( $rc )) && echo failure && exit 1
echo success
answered Aug 25 '17 at 2:23
jones77jones77
10616
10616
add a comment |
add a comment |
A slight variation of the answer given by @rrauenza. Since the && rc=$? part is their answer will always be equal to && rc=0 one can as well set rc to 0 before running the command. The result ends up more readable in my opinion because the variable is defined upfront in its own line of code and is only changed if the command exits with a non-zero exit status. If nounset is also given, then it's now clear that rc was indeed never undefined. This also avoids mixing && and || in the same line which might be confusing because one might not always know the operator precedence by heart.
#!/bin/sh
set -eu
rc=0
cat /tmp/doesnotexist || rc=$?
echo exitcode: $rc
rc=0
cat /dev/null || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
add a comment |
A slight variation of the answer given by @rrauenza. Since the && rc=$? part is their answer will always be equal to && rc=0 one can as well set rc to 0 before running the command. The result ends up more readable in my opinion because the variable is defined upfront in its own line of code and is only changed if the command exits with a non-zero exit status. If nounset is also given, then it's now clear that rc was indeed never undefined. This also avoids mixing && and || in the same line which might be confusing because one might not always know the operator precedence by heart.
#!/bin/sh
set -eu
rc=0
cat /tmp/doesnotexist || rc=$?
echo exitcode: $rc
rc=0
cat /dev/null || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
add a comment |
A slight variation of the answer given by @rrauenza. Since the && rc=$? part is their answer will always be equal to && rc=0 one can as well set rc to 0 before running the command. The result ends up more readable in my opinion because the variable is defined upfront in its own line of code and is only changed if the command exits with a non-zero exit status. If nounset is also given, then it's now clear that rc was indeed never undefined. This also avoids mixing && and || in the same line which might be confusing because one might not always know the operator precedence by heart.
#!/bin/sh
set -eu
rc=0
cat /tmp/doesnotexist || rc=$?
echo exitcode: $rc
rc=0
cat /dev/null || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
A slight variation of the answer given by @rrauenza. Since the && rc=$? part is their answer will always be equal to && rc=0 one can as well set rc to 0 before running the command. The result ends up more readable in my opinion because the variable is defined upfront in its own line of code and is only changed if the command exits with a non-zero exit status. If nounset is also given, then it's now clear that rc was indeed never undefined. This also avoids mixing && and || in the same line which might be confusing because one might not always know the operator precedence by heart.
#!/bin/sh
set -eu
rc=0
cat /tmp/doesnotexist || rc=$?
echo exitcode: $rc
rc=0
cat /dev/null || rc=$?
echo exitcode: $rc
Output:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
answered Dec 19 '18 at 9:12
joschjosch
3,71512629
3,71512629
add a comment |
add a comment |
A clean reliable way to error exit
command_that_error_exits || echo "Line $LINENO: Failed with Error" 1>&2; exit 1;
add a comment |
A clean reliable way to error exit
command_that_error_exits || echo "Line $LINENO: Failed with Error" 1>&2; exit 1;
add a comment |
A clean reliable way to error exit
command_that_error_exits || echo "Line $LINENO: Failed with Error" 1>&2; exit 1;
A clean reliable way to error exit
command_that_error_exits || echo "Line $LINENO: Failed with Error" 1>&2; exit 1;
answered Mar 28 at 21:53
Joviano DiasJoviano Dias
56346
56346
add a comment |
add a comment |
The accepted answer is good, but I think it could be refactored to be even better; more generic, easier to refactor and read:
some_command_status=$(some_command && echo $? || echo $?)
vs.
some_command && some_command_status=$? || some_command_status=$?
1
Note that using$(some_command ...)may create an extra subprocess (particularly in Bash) and cause performance problems. Also, there are rare circumstances where a command will behave significantly differently if run in a subprocess.
– pjh
Dec 13 '16 at 20:13
1
This won't work ifsome_commandproduces output.
– pjh
Dec 14 '16 at 11:07
add a comment |
The accepted answer is good, but I think it could be refactored to be even better; more generic, easier to refactor and read:
some_command_status=$(some_command && echo $? || echo $?)
vs.
some_command && some_command_status=$? || some_command_status=$?
1
Note that using$(some_command ...)may create an extra subprocess (particularly in Bash) and cause performance problems. Also, there are rare circumstances where a command will behave significantly differently if run in a subprocess.
– pjh
Dec 13 '16 at 20:13
1
This won't work ifsome_commandproduces output.
– pjh
Dec 14 '16 at 11:07
add a comment |
The accepted answer is good, but I think it could be refactored to be even better; more generic, easier to refactor and read:
some_command_status=$(some_command && echo $? || echo $?)
vs.
some_command && some_command_status=$? || some_command_status=$?
The accepted answer is good, but I think it could be refactored to be even better; more generic, easier to refactor and read:
some_command_status=$(some_command && echo $? || echo $?)
vs.
some_command && some_command_status=$? || some_command_status=$?
answered Apr 29 '16 at 22:46
Chris DunderChris Dunder
16925
16925
1
Note that using$(some_command ...)may create an extra subprocess (particularly in Bash) and cause performance problems. Also, there are rare circumstances where a command will behave significantly differently if run in a subprocess.
– pjh
Dec 13 '16 at 20:13
1
This won't work ifsome_commandproduces output.
– pjh
Dec 14 '16 at 11:07
add a comment |
1
Note that using$(some_command ...)may create an extra subprocess (particularly in Bash) and cause performance problems. Also, there are rare circumstances where a command will behave significantly differently if run in a subprocess.
– pjh
Dec 13 '16 at 20:13
1
This won't work ifsome_commandproduces output.
– pjh
Dec 14 '16 at 11:07
1
1
Note that using
$(some_command ...) may create an extra subprocess (particularly in Bash) and cause performance problems. Also, there are rare circumstances where a command will behave significantly differently if run in a subprocess.– pjh
Dec 13 '16 at 20:13
Note that using
$(some_command ...) may create an extra subprocess (particularly in Bash) and cause performance problems. Also, there are rare circumstances where a command will behave significantly differently if run in a subprocess.– pjh
Dec 13 '16 at 20:13
1
1
This won't work if
some_command produces output.– pjh
Dec 14 '16 at 11:07
This won't work if
some_command produces output.– pjh
Dec 14 '16 at 11:07
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9629710%2fproper-way-to-detect-shell-exit-code-when-errexit-option-set%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
Don't set
errexitif you want to handle errors. Handle errors if you want to handle errors. Settingerrexitis abdicating from your responsibility to handle errors properly. I've never found it necessary to usenounset, but I am reasonably good at spelling consistently.– Jonathan Leffler
Mar 9 '12 at 6:28
21
Always use errexit even if you want to handle errors. Any external command can fail and unless you plan on adding error handling for each|command|in|a&&work||flow then errexit will at least help protect you and the user. Same with nounset, not using it is like not using assert in other languages (because I never make errors, ever...)
– Paul Hargreaves
Sep 12 '12 at 20:54
FYI, none of these catch the full range of errexit codes. If your
bad_commandinternally calls another command, e.g.bad_com2, then errexit would crash the entire program. However, the checks listed here would miss the exit code ofbad_com2as long as it doesn't affect the exit code ofbad_command. Given that you're asking this question, you're probably well aware of this limitation, but others might think that these methods are a replacement for errexit :-)– Hamy
Jun 18 '14 at 6:54
My above comment shows a bad situation too - you can't have a 'test' for "will errexit causing a failure" - your only option is to enable it and see.
– Hamy
Jun 18 '14 at 6:56
1
@Daniel In your answer, you don't need backticks around
bad_command. I.e.,if ! bad_command; then ... fiis enough.– Linus Arver
Sep 14 '16 at 20:10