2つの関数定義の唯一の違いは、1つ目はlocal
保存キーワードを割り当てと組み合わせ、2つ目はそれを分離することです。
function foo {
local fn=$(mktemp -p /path/does/not/exist 2>/dev/null)
echo $?
}
function bar {
local fn
fn=$(mktemp -p /path/does/not/exist 2>/dev/null)
echo $?
}
foo
bar
最初は「0」、次に「1」です。まず「1」をエコーし、次に「1」をエコーしたい。値は、$?
コマンド置換の結果ではなく、ローカルに割り当てた結果のようです。
bash 4.2.46(1) - リリースはなぜこのように動作しますか?
答え1
私はこの動作が問題なので明示的に文書化されたと思いましたが(特に-o errexit
!でbashスクリプトを実行するとき)、そうではありません。私のマニュアルのコピーには次のように指定されています(about、global
関数の内部と同じように動作します)。local
無効なオプションが見つからない限り、 '-f foo=bar' を使用して関数を定義し、読み取り専用変数に値を割り当ててみて、複合割り当て構文を使わずに配列変数に値を割り当ててみてください。 [...] 、名前の1つが有効なシェル変数名ではありません。読み取り専用変数の読み取り専用状態をオフにしたり、配列変数の配列状態をオフにしたり、-fを使用して存在しない関数を表示したりします。それ以外の場合、戻り状態は0です。
したがって、これは他のプログラミング言語で予想されるキーワードとは見えませんlocal
。割り当てに似たパラメータが引数に指定されている場合は、local
代わりに初期化を制限しません。local
組み込みコマンド割り当ての発生を担当し、戻りコードはlocal
初期化プログラムで実行できるコードではなく、それ自体であり、その戻りコードは上記の条件リストでのみゼロではありません。
Bishopがコメントで述べたように、もう少し文字通り質問に答えるために、bash管理者であるChet Rameyは、local
割り当て中に反射が失敗することを考慮するかどうかを尋ねられ、基本的に次のように答えました。local
課題は主な仕事ではありません。
:
なぜなら、それは地域社会とその兄弟姉妹が[…]することではないからです。これらの組み込み関数は、変数属性を割り当てて変更するために存在します。アドオンとして割り当てもサポートする上で重要な機能はプロパティ設定です。値がどのように計算されるかを知る必要はありません。 [...]関数はプロパティまたは値を設定するため、終了ステータスは操作が成功したかどうかを反映する必要があります。
zsh
同じ動作がシェルでも観察できることは注目に値します。
解決策は、次の2つのタスクを分離することです。
local variable
variable=$( somecommand )
exit_status=$?