シェルローカル変数に終了コードを割り当てる

シェルローカル変数に終了コードを割り当てる
#!/bin/bash
function0()
{
 local t1=$(exit 1)
 echo $t1
}

function0

echonull 値を印刷します。私は期待:

1

変数に終了t1コマンドの戻り値が割り当てられていないのはなぜですか1

答え1

local t1=$(exit 1)シェルに次のように教えてください。

  • exit 1サブシェルで実行します。
  • その出力(標準出力に印刷されたテキストなど)を関数t1のローカル変数に保存します。

したがって、t1空のままで終わるのが正常です。

$()と呼ばれる。コマンドの置き換え.)

終了コードは常にに割り当てられているため、$?次のことができます。

function0()
{
  (exit 1)
  echo "$?"
}

希望の効果を得るために。もちろん、$?他の変数に割り当てることもできます。

function0()
{
  (exit 1)
  local t1=$?
  echo "$t1"
}

答え2

終了コードは次の場所に保存されます。$?変える使用コマンドの置き換え出力のみをキャプチャーするには、以下を使用する必要があります。(...) サブシェルの作成:

#!/bin/bash

func() {
  (exit 1)
  local t1=$?
  printf '%d\n' "$t1"
}

func

答え3

bashこの作品では:

loc(){  local   "x=$(exit "$1"):$?"
        printf  '$%s:\t%d\n' \
                 x "${x##*:}" \? "$?"
}

これは、コマンドの評価と変数の割り当て順序に関連しています。local独自の戻り値があります。これはコマンド置換ではなく、現在実行中のコマンドです。理由はまるで…

x=$(exit 1); echo "$?"

$x...このコマンドは、値を割り当てるためにサブシェルを実行する以外に戻り値がないため、1を返すことができます。したがって、$?コマンド置換が使用されるほとんどすべての場合のように中断されることはありません。

とにかくlocalそれでする破損しているが適切な時点で見つかった場合、拡張プログラムはまだ評価されています今後 localルーチンはそれを破壊する可能性がありますが、まだ割り当てることができます。

unset x; loc 130; echo "${x-\$x is unset}"

...印刷...

$x: 130
$?: 0
$x is unset

$?ただし、多くのシェルでは、この方法で実行される中間評価に頼ることができないことに注意する必要があります。実際、これはおそらく、これらのシェルがすべてbashの可能な瞬間に再評価しないためです。私の考えでは、これはおそらくbash。通訳者が値を使用する前に上書きする可能性のある値を再帰的に繰り返し評価することを本当に望みますか?

とにかく、あなたができることは次のとおりです。

答え4

@mikeservの答えは素晴らしく、私が見つけた動作の説明を提供しますが、なぜそのようなことが起こったのかわかりません。

localサブシェルの終了コードを食べることを防ぐ簡単な方法を追加したかったです。

val_check_exit() {
   local val=
   val=$(echo "hi"; exit 1)
   local res=$?
   echo "val is ${val}, exit code ${res}"
}
val_check_exit
# outputs:
# val is hi, exit code 1

関連情報