getline()
awk
GNU 함수를 사용하여 일부 명령을 실행 하고 반환된 오류 번호( ) 값을 인쇄하려고 합니다 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
GNU 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;
}
}'