AWK中最后一条命令的访问返回码

A.D*_*.D. 2 awk exit-status

找不到命令应该产生返回码127

$ foo; echo $?
bash: foo: command not found...
127
Run Code Online (Sandbox Code Playgroud)

我试图分配$?给变量rc然后打印它,但 RC 总是0.

$ foo | awk -v rc="$?" 'BEGIN{print rc}'
0
bash: foo: command not found...
Run Code Online (Sandbox Code Playgroud)

发现它只会在这种情况下打印正确的 RC:

$ qazqaz
bash: qazqaz: command not found...
$ foo | awk -v rc="$?" 'BEGIN{print rc}'
127
bash: foo: command not found...
Run Code Online (Sandbox Code Playgroud)

使用管道时是否可以在 awk 中使用 RC?还是其他地方的问题?

我想坚持使用一些旧的便携式 awk 实现。

Sté*_*las 5

在管道中,命令同时运行。这就是重点,一个的输出实时馈送到另一个。

您只知道命令返回时的退出状态。如果您想awk处理 的输出foo并访问其退出状态,则需要在将的输出存储在某处后运行awk 例如:foofoo

foo > file
awk -v "rc=$?" '{print rc, $0}' < file
Run Code Online (Sandbox Code Playgroud)

或者,您可以自己awk运行foo(好吧,仍然通过 shell 来解释命令行),读取其输出(通过管道通过其cmd | getline接口到popen())并使用以下命令获取其退出状态:

awk -v cmd=foo '
  BEGIN {
    while ((cmd | getline) > 0) {
      print
    }
    rc = close(cmd)
    print rc
  }'
Run Code Online (Sandbox Code Playgroud)

但是请注意,awk退出状态的编码方式因awk实现而异。在某些情况下,它是直接由waitpid()or返回的状态pclose(),在其他情况下,它是除以 256(即使foo被信号杀死)......尽管rc当且仅当命令成功时,您应该能够依赖于0。

在这种情况下gawk它最近确实发生了变化

或者你可以通过管道在最后输入退出状态:

(foo; echo "$?") | awk '
   {saved = $0}
   NR > 1 {
     # process the previous line
     $0 = prev
     print "output:", $0
   }
   {prev = saved}
   END{rc = prev; print rc}'
Run Code Online (Sandbox Code Playgroud)

(假设foo的输出在它不为空(是有效文本)时以换行符结尾)。

或者通过单独的管道喂食。例如在 Linux 上使用 ksh93 以外的 shell:

{ : extra pipe | { (foo 3<&-; echo "$?" > /dev/fd/3) | awk '
  {print}
  END {getline rc < "/dev/fd/3"; print rc}'
} 3<&0 <&4 4<&-; } 4<&0
Run Code Online (Sandbox Code Playgroud)