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

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

未找到命令应产生返回代码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 foofoo的输出存储在类似以下位置之后:

foo > file
awk -v "rc=$?" '{print rc, $0}' < file

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

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

awk但请注意,退出状态的编码方式因不同的awk实现而异。在某些情况下,它是由waitpid()or返回的状态pclose(),在其他情况下,它是 1 除以 256(即使被信号杀死)...尽管当且仅当命令成功时,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 以外的 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

答案2

使用 type 命令等:

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

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

相关内容