Awk는 빈 인수가 지정되는 방식에 따라 다르게 응답합니다.

Awk는 빈 인수가 지정되는 방식에 따라 다르게 응답합니다.

아마도 awk의 버그일 수도 있지만 bash/awk에 대한 이해의 버그일 수도 있습니다.

Python 프로그램의 출력이 awk로 파이프되는 문제를 디버깅하려고 했는데 awk 명령이 수행하는 작업에 관계없이 다음 예외가 발생했습니다.

close failed in file object destructor:
Error in sys.excepthook:

Original exception was:

결과적으로 awk는 빈 첫 번째 인수를 전달한 다음 -f awkfilename.awk. 따라서 다음 명령줄을 사용하여 오류를 재현할 수 있습니다.

python -c 'print "hello"'  | awk '' 

그러나 인수 없이 awk를 실행하면(위에서 동등한 것으로 간주하는 것임) awk 도움말과 동일한 예외가 발생합니다.

 python -c 'print "hh"'  | awk 

Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options:      GNU long options:
    -f progfile     --file=progfile
    -F fs           --field-separator=fs
    -v var=val      --assign=var=val
    -m[fr] val
    -W compat       --compat
    -W copyleft     --copyleft
    -W copyright        --copyright
    -W dump-variables[=file]    --dump-variables[=file]
    -W exec=file        --exec=file
    -W gen-po       --gen-po
    -W help         --help
    -W lint[=fatal]     --lint[=fatal]
    -W lint-old     --lint-old
    -W non-decimal-data --non-decimal-data
    -W profile[=file]   --profile[=file]
    -W posix        --posix
    -W re-interval      --re-interval
    -W source=program-text  --source=program-text
    -W traditional      --traditional
    -W usage        --usage
    -W use-lc-numeric   --use-lc-numeric
    -W version      --version

To report bugs, see node `Bugs' in `gawk.info', which is
section `Reporting Problems and Bugs' in the printed version.

gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output.

Examples:
    gawk '{ sum += $1 }; END { print sum }' file
    gawk -F: '{ print $1 }' /etc/passwd
close failed in file object destructor:
Error in sys.excepthook:

Original exception was:

메모:"원래 예외는 다음과 같습니다:" 이후의 메시지는 실제로 비어 있으며 건너뛴 것이 아닙니다.

내 시스템에 대한 세부정보

Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2

$ awk --version
GNU Awk 3.1.6

$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04.3 LTS

$ uname -a
Linux <hostname> 2.6.32-37-generic #81-Ubuntu SMP Fri Dec 2 20:32:42 UTC 2011 x86_64     GNU/Linux

누군가가 통찰력을 제공할 수 있다면 기쁠 것입니다. 물론 즉각적인 해결책은 awk에 비어 있는 것으로 전달되는 인수를 정리하는 것인데, 이로 인해 원인이 궁금했습니다.

편집

아래 설명에 따르면 두 번째 호출은 awk가 인수 수를 0 대신 1(인수는 빈 문자열임)로 본다는 점에서 다릅니다 awk.awk ''

내가 아직도 이해하지 못하는 것은 awk 표현처럼 빈 문자열이 하는 일이 무엇인지입니다.

예를 들어 다음은 잘 작동합니다

$ echo "" > /tmp/empty.awk
$ python -c 'print "hello"' | awk -f /tmp/empty.awk
$ echo $?
$ 0

답변1

여기에는 두 가지 별도의 작업이 진행됩니다. 오류 메시지(실제로 awk가 아닌 Python에서 온 메시지)와 awk의 사용 메시지입니다. 이를 격리하려면 두 명령 모두에서 stderr을 리디렉션하면 됩니다.

$ python -c 'print "hello"' 2>pyerr | awk 2>awkerr
$ cat pyerr 
close failed in file object destructor:
Error in sys.excepthook:

Original exception was:
$ cat awkerr 
usage: awk [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]

AIUI Python에 오류가 발생하는 이유는 Python이 쓰기 전에 프로그램의 출력이 파이프로 연결되어 종료(& 파이프를 닫음)되기 때문입니다. 다음은 sleep 0아무것도 하지 않고 매우 빠르게 종료되는 프로그램을 사용하는 예입니다 .

$ python -c 'print "hello"' | sleep 0
close failed in file object destructor:
Error in sys.excepthook:

Original exception was:

하지만 을 사용하면 sleep 1python이 쓰기를 완료할 때까지 sleep이 파이프 끝을 닫지 않기 때문에 오류가 없습니다. 관련된 정확한 타이밍에 따라 결과가 다를 수 있습니다.

이제 awk오류가 발생했습니다. 차이점은 awk인수가 없으면 유효하지 않다는 것입니다.~ 해야 하다프로그램을 제공하고; 부적절하게 실행했기 때문에 실행 방법을 알려주는 사용법 메시지를 인쇄하여 도움을 주려고 합니다. 반면에 awk ''실제로 awk에게 빈 스크립트('')를 실행하라고 지시하는 것입니다. 이는 완벽하게 유효하므로(매우 유용하지는 않지만) 사용법 메시지가 인쇄되지 않습니다.

$ awk
usage: awk [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]
$ awk ''

답변2

인수(또는 매개변수)가 없는 프로그램을 호출하는 것은 하나의 비어 있는 인수(또는 매개변수)를 사용하여 프로그램을 호출하는 것과 다릅니다.

일부 C 코드를 예로 사용하려면 다음을 수행하십시오.

#include <stdio.h>
int main(int argc, char** argv)
{
    printf("%d\n", argc); // print the number of arguments we've received
    return 0; // exit successfully
}

이 프로그램을 실행하면 example인쇄됩니다 1. 프로그램 이름이 항상 자동으로 전달되고 추가 인수가 없기 때문입니다. 프로그램 이름과 빈 매개변수 또는 가 있으므로 프로그램을 example ''또는 로 실행하면 example SomethingGoesHere가 인쇄됩니다 .2SomethingGoesHere

awk는 최소 2개의 매개변수(이름 및 기타 항목)를 기대하므로 인수 없이 awk 자체를 호출하면 위에서 볼 수 있는 결과, 즉 도움말이 인쇄됩니다.

이러한 이유로 인수를 적절하게 정렬할 수 있습니다. 항상 3개의 인수가 필요한 프로그램이 있지만 두 번째 인수를 공백으로 두려는 경우 간단히 생략할 수 없습니다. 쉘은 생략된 인수가 있다는 것을 알지 못하므로 2개의 인수를 전달합니다. 프로그램에 오류가 발생하게 됩니다.

관련 정보