找不到命令应该产生返回码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 实现。
在管道中,命令同时运行。这就是重点,一个的输出实时馈送到另一个。
您只知道命令返回时的退出状态。如果您想awk
处理 的输出foo
并访问其退出状态,则需要在将的输出存储在某处后运行awk
, 例如:foo
foo
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)