未找到命令应产生返回代码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
(好吧,仍然通过 shell 来解释命令行),读取其输出(通过其接口通过管道cmd | getline
)popen()
并通过以下方式获取其退出状态:
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