見つからないコマンドは戻りコードを生成する必要があります127
。
$ foo; echo $?
bash: foo: command not found...
127
$?
変数に割り当ててから印刷してみましたが、rc
RCは常に0
。
$ foo | awk -v rc="$?" 'BEGIN{print rc}'
0
bash: foo: command not found...
この場合にのみ正しいRCが印刷されることを確認しました。
$ qazqaz
bash: qazqaz: command not found...
$ foo | awk -v rc="$?" 'BEGIN{print rc}'
127
bash: foo: command not found...
パイプを使用するときにawkでRCを使用できますか?それとも問題が別の場所にありますか?
私は古いポータブルawkの実装に固執したいと思います。
ベストアンサー1
パイプラインでは、コマンドは同時に実行されます。つまり、ある出力がリアルタイムで別の出力に渡されるということです。
コマンドが返されたときにのみ、コマンドの終了状態を知ることができます。awk
出力を処理して終了ステータスにアクセスするには、foo
以下を実行する必要があります。awk
後ろに foo
出力をfoo
次のような場所に保存した後:
foo > file
awk -v "rc=$?" '{print rc, $0}' < file
または、直接awk
実行してfoo
(コマンドラインを解釈するシェルを使用して)出力を読み込み(インターフェースを介してパイプ処理cmd | getline
)、popen()
次のように終了ステータスを取得することもできます。
awk -v cmd=foo '
BEGIN {
while ((cmd | getline) > 0) {
print
}
rc = close(cmd)
print rc
}'
awk
ただし、終了ステータスがエンコードされる方法は実装awk
ごとに異なります。場合によっては、またはwaitpid()
によって返された状態で、他の場合は1を256で割ります(信号で終了した場合でも)...しかし、pclose()
コマンドが成功した場合にのみfoo
0に依存できるはずです。rc
の場合gawk
、最近は間違いなく状況が変わりました。。
または、最後に終了ステータスをパイプすることもできます。
(foo; echo "$?") | awk '
{saved = $0}
NR > 1 {
# process the previous line
$0 = prev
print "output:", $0
}
{prev = saved}
END{rc = prev; print rc}'
(家foo
の出力は空でない場合は改行で終わります(有効なテキストです))。
または別々のパイプラインを介して供給されます。たとえば、Linuxでksh93以外のシェルを使用している場合:
{ : extra pipe | { (foo 3<&-; echo "$?" > /dev/fd/3) | awk '
{print}
END {getline rc < "/dev/fd/3"; print rc}'
} 3<&0 <&4 4<&-; } 4<&0