명령이 실패하면 GNU awk ERRNO가 설정되지 않습니다.

명령이 실패하면 GNU awk ERRNO가 설정되지 않습니다.

getline()awkGNU 함수를 사용하여 일부 명령을 실행 하고 반환된 오류 번호( ) 값을 인쇄하려고 합니다 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 resultcmd다음 출력이 으로 파이프됩니다 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.


cmdGNU awk는 posix 모드가 아닌 경우 상태를 반환하므로 다음을 수행할 수 있습니다.

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;
    }
}'

관련 정보