0

私の目的は、stderr と stdout を区別し、終了コードを取得できるようにしながら、パイプを作成せずに子プロセスを監視することです。SIGKILL の場合にクリーンアップされないため、名前付きパイプまたは /dev/shm の使用を避けたいと思います (はい、私には親切で機知に富んだユーザーがいます)。

4

1 に答える 1

0

stackoverflow でアイデアを選んだ後、これにたどり着きました。それが最も賢明な方法であるかどうかはわかりませんが、お気軽に修正/強化してください!

% monitor "echo stdout:" "echo stderr:" /bin/bash -c "echo FOO;BAR"
stdout: FOO
stderr: /bin/bash: BAR: command not found
% echo Exit-code: $?
Exit-code: 127

リダイレクトごとに1つずつ、2つの子プロセスを生成し続けるため、改善の余地があります。

#
# PURPOSE 
#   redirect stdout and stderr to 2 distinct functions and retrieve exit code
#
# USAGE 
#   monitor HANDLER_OUT HANDLER_ERR COMMAND ...
#   HANDLER_OUT and HANDLER_ERR can be commands or functions
#   COMMAND is the full command which outputs are being monitors
#
# RESULT
#   returns COMMAND exit-code
#
# EXAMPLES
#   monitor "echo OUT=" "echo ERR=" /bin/bash -c "FOOBAR; echo Done."
#   monitor myfunction1 myfunction2 /bin/bash -c "FOOBAR; echo Done.;/bin/false"
#
monitor () {
    monitor_exit_code "$@" 1001>&1 1002>&2
}

monitor_exit_code () {
    local code=0
    while read data
    do
        code=$data
    done < <( monitor_stdout "$@" 1000>&1 )
    return $code
}


monitor_stdout () {
    local parser_out=$1;shift
    while read data
    do
        ($parser_out "$data") >&1001 
    done < <( monitor_stderr "$@" 1001>&1 )
}

monitor_stderr () {
    local parser_err=$1;shift
    while read data
    do
        ($parser_err "$data") >&1002 
    done < <( "$@" 2>&1 1>&1001 ; echo >&1000 $?  ) 
}
于 2013-09-24T13:02:47.727 に答える