web-dev-qa-db-ja.com

evalからの戻り値

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を引数として取ると、nonsense127を返すことが期待されます。

evalの引数の終了ステータスを取得する方法は?

7
Viesturs

次の場合-

`nonsense`
echo $?

あなたは基本的に「無意味なコマンドの出力を取得しようとしたときに終了ステータスを教えてください」と尋ねていますが、その答えは「コマンドが見つかりません」または127です。

しかし、次のことをすると

eval `nonsense`
echo $?

引数なしでevalを実行するのと同じ「空の文字列を評価するときにevalの終了ステータスを教えて」(ナンセンスコマンドの出力)を質問しています。

evalは引数なしで実行しても問題なく、その終了ステータスは0になります

8
amisax

実際には、それだけではありません。

$ `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の終了ステータスが含まれます。

また、$outputcmd2に対してのみ設定されます。その例外は、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がコマンドを実行しない限り)

13