Bashマニュアルには次のように記載されています。
eval [arg ...]
The args are read and concatenated together into a single com-
mand. This command is then read and executed by the Shell, and
its exit status is returned as the value of eval. If there are
no args, or only null arguments, eval returns 0.
やってみる
eval `nonsense`
echo $?
結果は0
です。
逆引用符で囲まれたコマンドを個別に実行すると、
`nonsense`
echo $?
結果は127
です。
Bashマニュアルの記述から、逆引用符付きのeval
を引数として取ると、nonsense
が127
を返すことが期待されます。
eval
の引数の終了ステータスを取得する方法は?
次の場合-
`nonsense`
echo $?
あなたは基本的に「無意味なコマンドの出力を取得しようとしたときに終了ステータスを教えてください」と尋ねていますが、その答えは「コマンドが見つかりません」または127です。
しかし、次のことをすると
eval `nonsense`
echo $?
引数なしでeval
を実行するのと同じ「空の文字列を評価するときにevalの終了ステータスを教えて」(ナンセンスコマンドの出力)を質問しています。
eval
は引数なしで実行しても問題なく、その終了ステータスは0になります
実際には、それだけではありません。
$ `nonsense`
bash: nonsense: command not found
$ echo "$?"
127
これは驚くべきことです。
bash
のstdoutでsplit + glob演算子の結果であるコマンドを実行するようにnonsense
に要求しています。 nonsense
は出力を生成しないため、コマンドは実行されないため、終了ステータスは0であると考えるかもしれません。
ただし、実際には、単純なコマンドラインに引数がなく、割り当てまたはリダイレクトのみがある場合、終了ステータスは、割り当ての最後のコマンド置換と、実行された(リダイレクトターゲットではなく)通常の単語のステータスになります(リダイレクトの失敗も影響します)。終了ステータス)。
これは、割り当てで特に役立ちます。
に:
output=$(grep pattern file)
status=$?
grep
の出力ステータスと終了ステータスの両方を取得できますが、$?
がそれ以外の場合はその非コマンドの終了ステータスである場合は取得できませんでした。
に:
output=$(cmd1) cmd2
これは、代入語と引数語の両方が存在する場所であり、cmd1
の終了ステータスは無視されます。 $?
には、cmd2
の終了ステータスが含まれます。
また、$output
はcmd2
に対してのみ設定されます。その例外は、cmd2
が特別な組み込みである場合です。
eval
はそのような特別な組み込みです。
$ a=0; a=1 eval; echo "$a"
1
bash
および最新のPOSIXシェルで。
a=`exit 5` eval; echo "$?"
または
eval `exit 5`; echo "$?"
引数なしでeval
を実行した結果であるため、0を出力します。しかし、それはBourne Shellやksh88には当てはまりません。特別なビルトインの場合、そこにexit 5
の終了ステータスが表示されます。
これらのシェルには、次のものもあります。
$ a=`exit 3` set x; echo "$?"
3
set
は別の特別な組み込み関数です。
.
は、もう1つの特別な組み込み関数です。 Bourne Shellとksh88では:
$ . /some/file `exit 4`; echo "$?"
4
(/some/file
がコマンドを実行しない限り)