回答:
これは、(POSIXの場合) Open Group Base仕様のセクション2.9.1の単純なコマンドに記載されています。そこにはテキストの壁があります。私はあなたの注意を最後の段落に向けます:
コマンド名がある場合は、「コマンドの検索と実行」で説明されているように実行が継続されます。コマンド名はないが、コマンドにコマンド置換が含まれている場合、コマンドは、最後に実行されたコマンド置換の終了ステータスで完了します。それ以外の場合、コマンドはゼロの終了ステータスで完了します。
したがって、たとえば、
Command Exit Status
$ FOO=BAR 0 (but see also the note from icarus, below)
$ FOO=$(bar) Exit status from "bar"
$ FOO=$(bar) baz Exit status from "baz"
$ foo $(bar) Exit status from "foo"
これもbashの仕組みです。ただし、最後の「それほど単純ではない」セクションも参照してください。
phk、彼の質問では、割り当ては、コマンド置換がある場合を除いて、終了ステータスを持つコマンドのようなものですか?、提案
...割り当て自体がコマンドとしてカウントされるように見えます...終了値がゼロですが、割り当ての右側の前に適用されます(たとえば、コマンド置換呼び出し...)
それはひどい見方ではありません。単純なコマンドのリターン・ステータスを決定するための粗スキーム(一方は含有しない;
、&
、|
、&&
または||
)です。
$(…)
そのコマンドから終了ステータスを取得します。回線の戻り状況は、最後に遭遇した番号です。
コマンドの引数としてのコマンド置換、たとえば、foo $(bar)
はカウントされません。から終了ステータスを取得しますfoo
。phkの表記を言い換えると、ここでの動作は
temporary_variable = EXECUTE( "bar" )
overall_exit_status = EXECUTE( "foo", temporary_variable )
しかし、これは少し単純化しすぎています。からの全体的な返品ステータス
A = $(cmd 1)B = $(cmd 2)C = $(cmd 3)D = $(cmd 4)E = mc 2からの終了ステータスです。後に発生した割り当て割り当ては0に全体的な終了ステータスを設定しません。
cmd4
E=
D=
イカロスは、phkの質問に対する彼の回答で、重要な点を挙げています。変数は読み取り専用として設定できます。POSIX標準のセクション2.9.1の最後から3番目の段落は、
変数割り当てのいずれかが、現在のシェル環境でreadonly属性が設定されている変数に値を割り当てようとすると(割り当てがその環境で行われたかどうかに関係なく)、変数割り当てエラーが発生します。これらのエラーの影響については、シェルエラーの影響を参照してください。
だからあなたが言うなら
readonly A
C=Garfield A=Felix T=Tigger
リターン・ステータスは1です。それ問題ではない場合は、文字列Garfield
、Felix
および/またはTigger
コマンド置換(S)で置き換えられている-しかし、下記の注意事項を参照してください。
セクション2.8.1シェルエラーの結果には、別の一連のテキストと表があり、
対話型シェルが終了しないようにする必要がある表に示されているすべてのケースで、シェルは、エラーが発生したコマンドの以降の処理を実行してはなりません。
詳細のいくつかは理にかなっています。一部はしません:
A=
割り当ては時々中止し、その最後の文は、指定しているようだとして、コマンドラインを。上記の例でC
は、はに設定されていますがGarfield
、設定されていT
ません(もちろん、どちらも設定されていません A
)。C=$(cmd1) A=$(cmd2) T=$(cmd3)
cmd1
cmd3
cmd2
私のバージョンのbashでは、
読み取り専用A C = 何か A = 何か T = 何か cmd 0
実行。特に、cmd0
C = $(cmd 1)A = $(cmd 2)T = $(cmd 3) cmd 0andを 実行しますが、は実行しません。(これはコマンドがない場合の動作とは逆です。)そして、の環境で(および)を設定します。これはbashのバグかと思います。
cmd1
cmd3
cmd2
T
C
cmd0
この回答の最初の段落は、「単純なコマンド」に言及しています。 仕様によると、
「単純なコマンド」は、オプションの変数の割り当てとリダイレクトのシーケンスであり、任意の順序で続き、オプションで単語とリダイレクトが続き、制御演算子によって終了されます。
これらは、最初のサンプルブロックのステートメントと同様です。
$ FOO=BAR
$ FOO=$(bar)
$ FOO=$(bar) baz
$ foo $(bar)
最初の3つには変数の割り当てが含まれ、最後の3つにはコマンドの置換が含まれます。
しかし、一部の変数の割り当てはそれほど単純ではありません。 bash(1)は言う、
代入文もの引数として表示されることがあり
alias
、declare
、typeset
、export
、readonly
、およびlocal
コマンド(組み込み宣言コマンド)。
についてexport
は、POSIX仕様によれば、
終了ステータス
0
すべての名前オペランドが正常にエクスポートされました。
> 0少なくとも1つの名前をエクスポートできなかったか、
-p
オプションが指定されていてエラーが発生しました。
そしてPOSIXはをサポートしていませんlocal
が、bash(1)はこう言っています、
local
関数内でない場合に使用するとエラーになります。local
関数の外で使用したり、無効な名前を指定したり、名前が読み取り専用変数である場合を除き、戻りステータスは0 です。
行の間を読むと、次のような宣言コマンドがわかります
export FOO=$(bar)
そして
local FOO=$(bar)
より似ています
foo $(bar)
彼らはから終了ステータスを無視する限りbar
、あなたのメインコマンドに基づいて、終了ステータスを与える(export
、local
、またはfoo
)。だから私たちは奇妙な
Command Exit Status
$ FOO=$(bar) Exit status from "bar"
(unless FOO is readonly)
$ export FOO=$(bar) 0 (unless FOO is readonly,
or other error from “export”)
$ local FOO=$(bar) 0 (unless FOO is readonly,
statement is not in a function,
or other error from “local”)
私たちはそれで実証することができます
$ export FRIDAY=$(date -d tomorrow)
$ echo "FRIDAY = $FRIDAY, status = $?"
FRIDAY = Fri, May 04, 2018 8:58:30 PM, status = 0
$ export SATURDAY=$(date -d "day after tomorrow")
date: invalid date ‘day after tomorrow’
$ echo "SATURDAY = $SATURDAY, status = $?"
SATURDAY = , status = 0
そして
myfunc() {
local x=$(echo "Foo"; true); echo "x = $x -> $?"
local y=$(echo "Bar"; false); echo "y = $y -> $?"
echo -n "BUT! "
local z; z=$(echo "Baz"; false); echo "z = $z -> $?"
}
$ myfunc
x = Foo -> 0
y = Bar -> 0
BUT! z = Baz -> 1
幸いにもShellCheckは、エラーをキャッチし、提起SC2155ことをアドバイスし、
export foo="$(mycmd)"
に変更する必要があります
foo=$(mycmd)
export foo
そして
local foo="$(mycmd)"
に変更する必要があります
local foo
foo=$(mycmd)
FOO=$(bar)
)それの価値は理論的に両方の終了ステータスことを指摘し、割り当てが役割を果たしているかもしれませんが、参照unix.stackexchange.com/a/341013/117599
A=foo cmd
実行されるbashのバグですか?cmd
A
A
読み取り専用であり、コマンド・C=value₁ A=value₂ T=value₃
セットC
ではなくT
(とは、もちろん、A
設定されていない) -シェルが無視し、コマンドラインの処理終了T=value₃
、ためA=value₂
のエラーです。(2)Stack Overflowの質問へのリンクをありがとう—私はそれにコメントを投稿しました。
local=$(false)
終了値があります。これは、それをそのように設計した天才にとって、世界での十分な荒らしではありません。0
It is an error to use local when not within a function. The return status is 0 unless local is used outside a function, an invalid name is supplied, or name is a readonly variable.
local
結びついているか知っていますか?例えばlocal foo=$(bar)
?