簡単なスクリプトを書いた
#!/bin/bash -x
selentry=`ls -l / | sort ; ts=${PIPESTATUS[0]}`
echo $ts
ただし、$tsには何も表示されません。 $ts変数をどのように表示するのですか、それとも変数のコマンドから終了ステータスコードを取得するのですか?
selentry=`ls -l / | sort`
答え1
存在する:
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
0以外の場合は終了状態になる可能性があります)。)配列は次の場所にあります。割り当てコマンドInfluenceの影響を受けません。foo
zsh
$pipestatus
しかし、ここで(サブシェルの)終了状態に興味がない場合は、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]}