![命令失败时未设置 GNU awk ERRNO](https://linux22.com/image/150315/%E5%91%BD%E4%BB%A4%E5%A4%B1%E8%B4%A5%E6%97%B6%E6%9C%AA%E8%AE%BE%E7%BD%AE%20GNU%20awk%20ERRNO.png)
getline()
我尝试使用GNU 函数运行一些命令awk
并打印返回的错误号 ( errno
) 值。但对于不存在的目录/文件的简单故障情况,变量似乎没有被填充。
awk 'BEGIN {
cmd = "ls -lrth /non/existing/path"
while ( ( cmd | getline result ) > 0 ) {
print result
}
close(cmd); print ENVIRON["ERRNO"]
}'
当上面从 中输出错误字符串时ls
,该print
语句不会产生有效的错误号。我也尝试过从手册页使用PROCINFO["errno"]
和PROCINFO["ERRNO"]
哪个不起作用。我还尝试在关闭文件描述符之前打印它,但这也不起作用。ENOENT
在这种情况下,期望是错误的吗?
答案1
您无法使用 获取错误号getline
。在您的命令中,输出来自ls
,而不是print result
。
在形式 中cmd | getline result
,cmd
运行,然后其输出通过管道传输到getline
。1
如果有输出,则返回;0
如果失败,则返回 EOF -1
。问题是失败是由于运行getline
本身,而不是cmd
.例子:
awk 'BEGIN {
while ( ( getline result < "/etc/shadow") > 0 ) {
print result
}
print "XXX: ", ERRNO
}'
XXX: Permission denied
您将看到/etc/shadow
无法读取,因此getline
无法运行并报告变量错误ERRNO
。
cmd
请注意,如果不在 posix 模式下,GNU awk 将返回状态,因此您可以执行以下操作:
awk 'BEGIN {
cmd = "ls -lrth /non/existing/path"
while ( ( cmd | getline result ) > 0 ) {
print result
}
status=close(cmd);
if (status != 0) {
code=and(rshift(status, 8),0xFF)
printf("Exit status: %d, exit code: %d\n", status, code)
}
}'
ls: cannot access '/non/existing/path': No such file or directory
Exit status: 512, exit code: 2
在 POSIX 模式下,您不会获得退出状态:
POSXILY_CORRECT=1 awk 'BEGIN {
cmd = "ls -lrth /non/existing/path"
while ( ( cmd | getline result ) > 0 ) {
print result
}
status=close(cmd);
if (status != 0) {
code=and(rshift(status, 8),0xFF)
printf("Exit status: %d, exit code: %d\n", status, code)
}
}'
ls: cannot access '/non/existing/path': No such file or directory
答案2
ERRNO 只能由 gawk 设置(GNU awk仅有的) 如果 getline 或 close 失败,但它成功读取 ls 的(空!)输出。该输出为空,因为 ls 在标准错误通道上给出错误消息(“ls:无法访问...”),不向标准输出写入任何内容,并且存在错误代码。
使用 GNU awk,您可以获得命令的退出状态,如下所示:
exitstatus=close(cmd)
if (exitstatus) {
# do something
}
如果您需要命令的错误消息,那么您必须将其标准错误通道重定向到某个文件,然后阅读:
awk 'BEGIN {
cmd = "ls -lrth /non/existing/path 2>standard-error.txt"
while ( ( cmd | getline result ) > 0 ) {
print result
}
es=close(cmd);
if (es) {
getline errstring < "standard-error.txt"
print "exitstatus "es" error message "errstring;
}
}'