Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pipe output and capture exit status in Bash

I want to execute a long running command in Bash, and both capture its exit status, and tee its output.

So I do this:

command | tee out.txt ST=$? 

The problem is that the variable ST captures the exit status of tee and not of command. How can I solve this?

Note that command is long running and redirecting the output to a file to view it later is not a good solution for me.

like image 497
flybywire Avatar asked Aug 03 '09 11:08

flybywire


People also ask

How do you check exit status in bash?

To check the exit code we can simply print the $? special variable in bash. This variable will print the exit code of the last run command.

How do you exit a pipe in Linux?

A pipe is created and the commands on the left ( #part3 ) and right ( #part2 ) are executed. exit $xs is also the last command of the pipe and that means the string from stdin will be the exit status of the entire construct. A subshell is created with file descriptor 3 redirected to stdout.

How does exit work in bash?

There are many methods to quit the bash script, i.e., quit while writing a bash script, while execution, or at run time. One of the many known methods to exit a bash script while writing is the simple shortcut key, i.e., “Ctrl+X”. While at run time, you can exit the code using “Ctrl+Z”.

How do I get exit status in shell?

You can simply do a echo $? after executing the command/bash which will output the exit code of the program. Every command returns an exit status (sometimes referred to as a return status or exit code).


2 Answers

There is an internal Bash variable called $PIPESTATUS; it’s an array that holds the exit status of each command in your last foreground pipeline of commands.

<command> | tee out.txt ; test ${PIPESTATUS[0]} -eq 0 

Or another alternative which also works with other shells (like zsh) would be to enable pipefail:

set -o pipefail ... 

The first option does not work with zsh due to a little bit different syntax.

like image 153
codar Avatar answered Sep 24 '22 23:09

codar


Dumb solution: Connecting them through a named pipe (mkfifo). Then the command can be run second.

 mkfifo pipe  tee out.txt < pipe &  command > pipe  echo $? 
like image 36
EFraim Avatar answered Sep 23 '22 23:09

EFraim