AWK で最後のコマンドの戻りコードにアクセスします。

AWK で最後のコマンドの戻りコードにアクセスします。

見つからないコマンドは戻りコードを生成する必要があります127

$ foo; echo $?
bash: foo: command not found...
127

$?変数に割り当ててから印刷してみましたが、rcRCは常に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()コマンドが成功した場合にのみfoo0に依存できるはずです。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

答え2

typeコマンドなどを使用してください。

type test > /dev/null 2>&1
echo $?
0

type fsfsf > /dev/null 2>&1
echo $?
1

関連情報