1

I have a bash script having the following command

rm ${thefile}

In order to ensure the command is execute successfully, I use $? variable to check on the status, but this variable doesn't show the exact error? To do this, I redirect the standard error output to a log file using following command:

rm ${file} >> ${LOG_FILE} 2>&1

With this command I can't use $? variable to check status on the rm command because the command behind the rm command is executed successfully, thus $? variable is kind of useless here.

May I know is there a solution that could combine both features where I'm able to check on the status of rm command and at mean time I'm allow to redirect the output?

4
  • 1
    " because the command behind the rm command is executed successfully" Please explain what you mean by this. $? will still return a value > 0 if rm failed. Commented May 27, 2014 at 2:56
  • What you have looks correct to me. Tested on my desktop too. Commented May 27, 2014 at 2:57
  • 2
    The assertion that 'with this command I can't use $? variable to check status on the rm command' is incorrect. The exit status of the command is independent of where the I/O redirection sends standard output and standard error (except that if the I/O redirections fail, the command is not executed at all). Given the false premise, it is not surprising that your conclusion 'thus $? variable is kind of useless here' is incorrect. You can use if rm ${file} >> ${LOG_FILE} 2>&1; then : OK; else : Failed; fi as just one of many ways of testing the status of the rm command. Commented May 27, 2014 at 3:18
  • Deepest regret posting this question while I was running some issues at production site. I was kind of mess just now and I didn't pay much attention on my verification. Thousand apologies on this mistake. Commented May 27, 2014 at 8:59

2 Answers 2

6

With this command I can't use $? variable to check status on the rm command because the command behind the rm command is executed successfully, thus $? variable is kind of useless here.

That is simply not true. All of the redirections are part of a single command, and $? contains its exit status.

What you may be thinking of is cases where you have multiple commands arranged in a pipeline:

command-1 | command-2

When you do that, $? is set to the exit status of the last command in the pipeline (in this case command-2), and you need to use the PIPESTATUS array to get the exit status of other commands. (In this example ${PIPESTATUS[0]} is the exit status of command-1 and ${PIPESTATUS[1]} is equivalent to $?.)

Sign up to request clarification or add additional context in comments.

8 Comments

While helpful, examining the elements of ${PIPESTATUS[@]} for any failure in a pipeline is somewhat cumbersome (cf. the pipefail option). Here's a shortcut: if (( ${PIPESTATUS[@]/%/ +} + 0 > 0 )); then echo "At least 1 command failed."; fi `
@mklement0: If you are looking for the exit-status of a specific command in a pipeline, PIPESTATUS is the best way to do that. (Partly because it's the only way to do that, and partly because it's a perfectly fine way to that.) I agree that it's not ideal if your goal is to determine if any command in a pipeline has failed, but this is veering increasingly far from the OP's actual question . . .
Point taken - and agreed - but since you brought up pipelines and PIPESTATUS and the OP's question is about failure in the abstract (no mention of multiple commands or pipelines), I thought I'd mention it. In light of you leading us down the yellow-pipe road, I suggest not punishing @konsolebox for it, though - commenting on how it's a tangent is fine, but the answer still has value.
@mklement0: I don't believe that konsolebox's answer has value on this page. I think it's fine for an answer to go on a tangent, if the answerer thinks that will be helpful; for example, konsolebox's answer could have value as part of an answer that either (1) answered the question or (2) explained why the question is ill-founded. But I don't think it's O.K. for an answer to start on a tangent, whereby it never has anything to do with the question.
@mklement0: (Even so, I wouldn't have downvoted if it weren't for his/her blatantly-false first sentence. The OP has an actual problem, or thinks (s)he does, and konsolebox's answer offers a putative solution that actually has nothing to do with that problem.)
|
1

What you probably need is the shell option pipefail in bash (from man bash):

The return status of a pipeline is the exit status of the last command, unless the pipefail option is enabled. If pipefail is enabled, the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero sta‐ tus, or zero if all commands exit successfully. If the reserved word ! precedes a pipeline, the exit status of that pipeline is the logical negation of the exit status as described above. The shell waits for all commands in the pipeline to terminate before returning a value.

> shopt -s -o pipefail
> true | false
> echo $?
1
> false | true
> echo $?
1
true | true
echo $?
0

3 Comments

+1; the advantage of shopt -so pipefail over using ${PIPESTATUS[@]} is that you don't need to search through the elements of the latter to find a nonzero exit code; however, restoring the value of the pipefail option afterward may be required.
-1, sorry. This does not answer the question. The OP is not using a pipeline, so obviously (s)he does not need pipefail.
For context: This answer is based on inferring from the OP's statement that the command behind the rm command is executed successfully that a [command] pipeline may be in the mix and thus explains how to detect failure in a pipeline.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.