Ric*_*sen 10 awk posix getline
在POSIX awk中,如何通过处理输出command 后获取退出状态(返回代码)command | getline var?exit 1如果command以非零退出状态退出,我想要我的awk脚本.
例如,假设我有一个名为的awk脚本foo.awk,如下所示:
function close_and_get_exit_status(cmd) {
# magic goes here...
}
BEGIN {
cmd = "echo foo; echo bar; echo baz; false"
while ((cmd | getline line) > 0)
print "got a line of text: " line
if (close_and_get_exit_status(cmd) != 0) {
print "ERROR: command '" cmd "' failed" | "cat >&2"
exit 1
}
print "command '" cmd "' was successful"
}
Run Code Online (Sandbox Code Playgroud)
然后我想要发生以下事情:
$ awk -f foo.awk
got a line of text: foo
got a line of text: bar
got a line of text: baz
ERROR: command 'echo foo; echo bar; echo baz; false' failed
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)
根据awk的POSIX规范,command | getline成功输入返回1,文件结束返回0,错误返回-1.如果command退出具有非零退出状态,则不是错误,因此不能用于查看是否command已完成且已失败.
同样,close()不能用于此目的: close()仅在关闭失败时返回非零,而不是在关联命令返回非零退出状态时返回非零.(在gawk中,close(command)返回退出状态command.这是我想要的行为,但我认为它违反了POSIX规范,并且并非awk的所有实现都以这种方式运行.)
awk system()函数返回命令的退出状态,但据我所知,没有办法使用getline它.
最简单的做法是在命令执行后从 shell 中回显退出状态,然后使用 getline 读取该状态。例如
$ cat tst.awk
BEGIN {
cmd = "echo foo; echo bar; echo baz; false"
mod = cmd "; echo \"$?\""
while ((mod | getline line) > 0) {
if (numLines++)
print "got a line of text: " prev
prev = line
}
status = line
close(mod)
if (status != 0) {
print "ERROR: command '" cmd "' failed" | "cat >&2"
exit 1
}
print "command '" cmd "' was successful"
}
$ awk -f tst.awk
got a line of text: foo
got a line of text: bar
got a line of text: baz
ERROR: command 'echo foo; echo bar; echo baz; false' failed
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)
如果有人阅读本文并考虑使用 getline,请确保您阅读http://awk.freeshell.org/AllAboutGetline并首先完全理解这样做的所有注意事项和含义。