Rohith
Rohith

Reputation: 1167

Not able to fetch the exit status of a multiple commands (separated by PIPE) which got assigned to a variable

Below is the sample script which i am trying to execute; but it fails to fetch the exit status of $cmd; is there any other way to fetch its exit status..!?

cmd="curl -mddddddd google.com"
status=$($cmd | wc -l)
echo ${PIPESTATUS[0]}

I know that, if i replace status=$($cmd | wc -l) with $cmd | wc -l , i could fetch the exit status of $cmd using PIPESTATUS. But in my case i have to assign it to a variable (example: status in above case).

Please help me here..!

Regards, Rohith

Upvotes: 1

Views: 108

Answers (3)

pjh
pjh

Reputation: 8064

If the output of the command is text and not excessively large, the simplest way to get the status of the command is to not use a pipe:

cmd_output=$($cmd)
echo "'$cmd' exited with $?"
linecount=$(wc -l <<<"$cmd_output")
echo "'wc' exited with $?"

What counts as "excessively large" depends on the system, but I successfully tested the code above with a command that generated 50 megabytes (over one million lines) of output on an old Linux system.

If the output of the command is too big to store in memory, another option is to put it in a temporary file:

$cmd >tmpfile
echo "'$cmd' exited with $?"
linecount=$(wc -l <tmpfile)
echo "'wc' exited with $?"

You need to be careful when using temporary files though. See Creating temporary files in Bash and How create a temporary file in shell script?.

Note that, as with the OP's example code, the unquoted $cmd in the code examples above is dangerous. It should not be used in real code.

Upvotes: 2

H&#229;ken Lid
H&#229;ken Lid

Reputation: 23064

If you just want to echo the pipe status, you can redirect that to stderr. But you have to do it in the subshell.

status=$($cmd | wc -l; echo ${PIPESTATUS[0]} >&2)

Or you can capture both variables from the subshell using read

read -rd $'\0' status pstatus <<<$($cmd | wc -l; echo ${PIPESTATUS[0]})

Upvotes: 1

Igor S.K.
Igor S.K.

Reputation: 1039

What you're assigning to the status variable is not a status, but what $cmd | wc -l pipeline prints to standard output.

Why do you echo anyway? Try realstatus=${PIPESTATUS[0]}.


EDIT (After some digging and RTFMing...):

Just this -- realstatus=${PIPESTATUS[0]} -- doesn't seem to help, since $(command_substitution), which is in your code, is done "in a subshell environment", while PIPESTATUS is about "the most-recently-executed foreground pipeline"

If what you're trying to do in this particular case is to ensure the curl (aka $cmd) command was succesfull in the pipeline you should probably make use of pipefail option (see here).

Upvotes: 2

Related Questions