「ローカル」に終了コードをキャプチャさせる方法は?


11

私のプロジェクトには次のスニペットがあります:

local output="$(bash "${1##*/}")"
echo "$?"

これにより、常に0が出力されますlocalが、削除するlocalと、$?変数が正しく動作します。これは、サブシェルからの終了コードを想定しています。

私の質問は、終了値をキャプチャしながら、この変数をローカルに保つにはどうすればよいですか?


1
shellcheckこの問題を検出するだけでなく、unix.stackexchange.com / a / 281749/24718で解決策を提案します!
Waleed Khan

回答:


16
#!/bin/bash
thing() {
   local foo=$(asjkdh) ret="$?"
   echo "$ret"
}

これは127、「コマンドが見つかりません」の正しいエラーコードをエコーします。

を使用localして、複数の変数を定義できます。したがってRETlocal成功する前にサブシェルの終了コードをキャプチャし$?てゼロに設定するローカル変数も作成します。


bashこの式を左から右に評価することが保証されていますか?
Max Ried

私の知る限りでは、変数の割り当ては、このコンテキストでは左から右の順になっています。
DopeGhoti 2016年

@MaxRiedこれが確実に機能するという事実は、そうであることを示しているようです。しかし、POSIXやのbashリファレンスマニュアルからは、これに関する情報を見つけることができません。

10
余談ですが、すべて大文字の変数名を使用するのは不適切な形式です。シェルまたはシステムで意味のある変数用に予約されているすべての大文字の名前と、少なくとも1つの小文字の名前が記載されているpubs.opengroup.org/onlinepubs/009695399/basedefs/…のPOSIX環境変数仕様を参照してください。シェル変数と環境変数は名前空間を共有することに注意してください(衝突が発生した場合、前者に割り当てると後者を上書きできるため)。
Charles Duffy、

コメントは詳細な議論のためのものではありません。この会話はチャットに移動しました
terdon

27

割り当てる前にローカル変数を宣言します。

thing() {
  local output
  output="$(bash "${1##*/}")"
  echo "$?"
}

私の意見では、これは追加のRET変数を設定するよりも読みやすいです。YMMVはその上ですが、期待どおりに機能します。


2
これは、複数の割り当ての戻りコードをチェックしたい場合は明らかであるように、個別の変数を使用するよりもはるかに優れていlocal var1 var2 ...ます。
l0b0

@ l0b0ボブ私の叔父です。:D
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.