接続コマンドの終了状態

接続コマンドの終了状態

変数で無効なコマンドを実行したいですcmd。私はそれを私に失敗させ、終了ステータスを検索させることはできません。私が試すことができるのはパイプを接続することです。:これにより、成功した終了ステータスが得られます。

$ $cmd | :
$ echo $?
0

cmd今、単独で実行せずに終了ステータスを知りたいです。 BashではPIPESTATUS

実行しようとすると、bash -c "$cmd | : ; rc=$(echo ${PIPESTATUS[@]} | head -c1)"「無効な代替エラー」が発生します。

私の質問は次のとおりです

  1. ダッシュで最初のコマンドの終了ステータスを返す目標を達成するには?
  2. 私は何をしていますが、ダッシュエラーが発生しますか?

答え1

完全なシェル構文がある場合は、ifシェルが失敗しないことを使用できます。

if (eval "$cmd"); then
    : # do nothing, it worked
else
    printf 'Command %s failed with code %d\n' "$cmd" $?
fi

if ! eval…否定すると、終了コードは非表示になるため、より明確な構文は使用できません。 「何もしない」が存在するのは、シェル構文によるものです。必要コマンドを含むthenブロックは省略または空白にできません。

重要なのは、if評価されたコマンドが失敗してもシェルの失敗ではないことです。

角かっこはサブシェルでコマンドを実行します。これにより、コマンドがスクリプトに影響を与える変数を設定したり、exit 1スクリプトを完全に終了したりするなどの操作を実行できなくなります。

最後に、引用されていないコマンドが予期しない方法で単語を分離するので、eval私がどのように使用したか注意してください。$cmdがある場合、cmd='rm -Rf "foo * baz"'実行時に$cmd実際に実行されているのは次のとおりですrm -Rf \"foo * baz\"〜する*ディレクトリ内のすべてのファイルに展開され、すべてのエントリが削除されます(両方のファイル"fooと除外baz")。これはrmグローバル拡張前の3つのパラメータで、予想されたものとは異なります。eval一般的なシェルコマンドの解析が適用されるので、驚きが減ると思います。これがテキストファイルから読み取られた行ではなくスクリプト内に作成されたコマンドである場合は、他の安全な方法(配列を使用するなど)があります。

関連情報