Pipe output and capture exit status in Bash

后端 未结 15 1085
盖世英雄少女心
盖世英雄少女心 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:20

    Pure shell solution:

    % rm -f error.flag; echo hello world \
    | (cat || echo "First command failed: $?" >> error.flag) \
    | (cat || echo "Second command failed: $?" >> error.flag) \
    | (cat || echo "Third command failed: $?" >> error.flag) \
    ; test -s error.flag  && (echo Some command failed: ; cat error.flag)
    hello world
    

    And now with the second cat replaced by false:

    % rm -f error.flag; echo hello world \
    | (cat || echo "First command failed: $?" >> error.flag) \
    | (false || echo "Second command failed: $?" >> error.flag) \
    | (cat || echo "Third command failed: $?" >> error.flag) \
    ; test -s error.flag  && (echo Some command failed: ; cat error.flag)
    Some command failed:
    Second command failed: 1
    First command failed: 141
    

    Please note the first cat fails as well, because it's stdout gets closed on it. The order of the failed commands in the log is correct in this example, but don't rely on it.

    This method allows for capturing stdout and stderr for the individual commands so you can then dump that as well into a log file if an error occurs, or just delete it if no error (like the output of dd).

提交回复
热议问题