命令失败时未设置 GNU awk ERRNO

Ini*_*ian 4 awk gawk

我试图使用getline()GNU 的函数运行一些命令awk并打印errno返回的错误号 ( ) 值。但是对于不存在的目录/文件的简单失败案例,变量似乎没有被填充。

awk 'BEGIN {
        cmd = "ls -lrth /non/existing/path"
        while ( ( cmd | getline result ) > 0 ) {
            print result
        }
        close(cmd); print ENVIRON["ERRNO"]
}'
Run Code Online (Sandbox Code Playgroud)

当上面从 中输出错误字符串时ls,该print语句不会产生有效的错误号。我也从试图手册页使用PROCINFO["errno"]PROCINFO["ERRNO"]没有工作。我也尝试在关闭文件描述符之前打印它,这也不起作用。ENOENT在这种情况下期望是错误的吗?

cuo*_*glm 6

您无法使用getline. 在您的命令中,输出来自ls,而不是print result

在形式cmd | getline resultcmd运行时,那么它的输出被管道输送到getline。它返回1如果有输出,0如果EOF,-1失败。问题是失败来自运行getline本身,而不是cmd. 例子:

awk 'BEGIN {
while ( ( getline result < "/etc/shadow") > 0 ) {
            print result
        }
        print "XXX: ", ERRNO
}'
XXX:  Permission denied
Run Code Online (Sandbox Code Playgroud)

您会看到/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
Run Code Online (Sandbox Code Playgroud)

在 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
Run Code Online (Sandbox Code Playgroud)

  • @Inian 也许你的 gawk 版本不支持 POSIXLY_CORRECT,你可以试试 `awk --posix`。当您的 awk 函数之一无法运行时,会设置“ERRNO”变量。它与`cmd`无关。 (2认同)