stderrに何かが書き込まれたら実行を停止します。

stderrに何かが書き込まれたら実行を停止します。

Bashスクリプトでエラーを処理する際に問題があります。これまでbashで見たエラー処理ソリューションのどれも、このサンプルスクリプトでは機能しないようです。

#!/usr/bin/env bash
set -euo pipefail

eval $(do_stuff)
touch file

出力は次のとおりです

./script.sh: line 4: do_stuff: command not found

しかし、それにもかかわらず幸せにファイルを生成し続けますが、これが私が無効にしたいものです。私はstderrを別のプログラムにパイプし、出力を取得しながらプログラム全体を終了できると思いました。

unbuffer ./script.sh 2>&1|{ while read stdin; do echo $stdin;killall -9 bash;done; }

ただし、これは約5%の時間でのみ機能します。ほとんどの場合、スクリプトは早期に終了しません。

答え1

私が投稿したイベントをエレガントに処理する方法を見つけました。

eval() {
    if [[ -z "${@}" ]];then
        exit 1
    fi
    builtin eval "$@"
}

デフォルトの eval() 実装をオーバーライドし、入力が受信されない場合は終了します。ただし、この回答は依然として質問の件名に対する回答ではないため、受け入れません。

答え2

まず課題に変更してから評価してください。

例1(入力コマンドが無効な場合は停止):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echoasasas)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
h2.sh: line 5: echoasasas: command not found
trapped
[xiaobai@localhost ~]$ 

例2(出力が有効なコマンドでない場合は停止):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echo xxxxx)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
h2.sh: line 6: xxxxx: command not found
trapped
[xiaobai@localhost ~]$ 

例3(次のコマンドの実行を続ける):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echo ls)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
Android  CRITICAL  Documents
next
[xiaobai@localhost ~]$ 

例4(STDERRが別のシェルで実行されている場合は半分):

[xiaobai@localhost ~]$ cat /tmp/so.sh 
ls yyyyyy 2>/tmp/kas
[xiaobai@localhost ~]$ cat /tmp/kas
[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
echo "before"
e2=$(/bin/bash /tmp/so.sh)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
before
trapped
[xiaobai@localhost ~]$ cat /tmp/kas
ls: cannot access 'yyyyyy': No such file or directory
[xiaobai@localhost ~]$ 

関連情報