Pipe output and capture exit status in Bash

后端 未结 15 1300
盖世英雄少女心
盖世英雄少女心 2020-11-22 08:07

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=$?
         


        
15条回答
  •  长情又很酷
    2020-11-22 08:23

    It may sometimes be simpler and clearer to use an external command, rather than digging into the details of bash. pipeline, from the minimal process scripting language execline, exits with the return code of the second command*, just like a sh pipeline does, but unlike sh, it allows reversing the direction of the pipe, so that we can capture the return code of the producer process (the below is all on the sh command line, but with execline installed):

    $ # using the full execline grammar with the execlineb parser:
    $ execlineb -c 'pipeline { echo "hello world" } tee out.txt'
    hello world
    $ cat out.txt
    hello world
    
    $ # for these simple examples, one can forego the parser and just use "" as a separator
    $ # traditional order
    $ pipeline echo "hello world" "" tee out.txt 
    hello world
    
    $ # "write" order (second command writes rather than reads)
    $ pipeline -w tee out.txt "" echo "hello world"
    hello world
    
    $ # pipeline execs into the second command, so that's the RC we get
    $ pipeline -w tee out.txt "" false; echo $?
    1
    
    $ pipeline -w tee out.txt "" true; echo $?
    0
    
    $ # output and exit status
    $ pipeline -w tee out.txt "" sh -c "echo 'hello world'; exit 42"; echo "RC: $?"
    hello world
    RC: 42
    $ cat out.txt
    hello world
    

    Using pipeline has the same differences to native bash pipelines as the bash process substitution used in answer #43972501.

    * Actually pipeline doesn't exit at all unless there is an error. It executes into the second command, so it's the second command that does the returning.

提交回复
热议问题