簡単なスクリプトを書きました
#!/bin/bash -x
selentry=`ls -l / | sort ; ts=${PIPESTATUS[0]}`
echo $ts
しかし、$ tsは何も表示しません。 $ ts変数を表示するにはどうすればよいですか、または変数のコマンドから終了ステータスコードを取得するにはどうすればよいですか?
selentry=`ls -l / | sort`
に:
selentry=`ls -l / | sort ; ts=${PIPESTATUS[0]}`
より現代的なものと同じ:
selentry=$(ls -l / | sort ; ts=${PIPESTATUS[0]})
$(...)
内のコードは、サブシェル環境で実行されます(bash
およびksh93
以外のシェルの場合、別のシェルプロセスでも実行されます)。したがって、そのサブシェル内の変数に加えられた変更は、親シェルには影響しません。
あなたがするとき:
var=$(cmd)
ただし、cmd
の終了ステータスは$?
で利用可能になります。これは$PIPESTATUS
には適用されません。次の場合:
var=$(foo | bar)
含まれる値は1つだけです(サブシェルの終了コード。ここではbar
の終了ステータスになります(pipefail
オプションがオンになっている場合は、foo
がゼロ以外の場合)。$pipestatus
配列が割り当てコマンドの影響を受けないzsh
ではさらに悪化します。
ただし、ここで、(サブシェルの)sort
の終了ステータスを気にしない場合は、次のことができます。
selentry=$(ls -l / | sort; exit "${PIPESTATUS[0]}")
ts=$?
ここでは、次のこともできます。
exec 3< <(ls -l /) # here ls is started as an asynchronous command
ls_pid=$!
selentry=$(sort <&3)
sort_status=$?
wait "$ls_pid"
exec 3<&- # close that fd 3
ls_status=$?
あるいは:
{
selentry=$(sort)
sort_status=$?
wait "$!"
ls_status=$?
} < <(ls -l /)
変数割り当てをコマンド置換後も存続させるというより一般的な質問では、ksh93
で、${ cmd;}
形式のコマンド置換を使用できます(ただし、ksh93
は$PIPESTATUS
/$pipestatus
をサポートしていません)。
var=${
foo; c1=$?
bar; c2=$?
}
他のBourneのようなシェルには同等のものはありません。一時ファイルなど、他の手段を介してデータを渡す必要があります。
var=$(
foo; echo "c1=$?" > "$tempfile"
bar; echo "c2=$?" >> "$tempfile"
)
. "$tempfile"
またはここ:
selentry=$(
ls -l / | sort
typeset -p PIPESTATUS | sed '1s/PIPESTATUS/my_&/' > "$tempfile"
}
. "$tempfile"
ls_status=${my_PIPESTATUS[0]}