在指定空参数时,Awk以不同的方式响应

分享于 

7分钟阅读

电脑

  繁體 雙語

问题:

我似乎遇到了一些可以能是 Bug 中的,但它也可以能是我理解 bash/awk的一个 Bug。

我试图调试一个 python 程序输出的问题,并且我将获得以下异常,无论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的参数,但这使我对原因感到奇怪。

编辑

根据下面的注释,udnerstand和的区别在于第二个调用意味着awk看到的参数数量为 1 (。参数为空字符串) 而不是 0.

我仍然不明白的是,空字符串作为awk表达式做什么。

对于 比如,以下工作正常


$ echo"">/tmp/empty.awk


$ python -c 'print"hello"' | awk -f/tmp/empty.awk


$ echo $?


$ 0




回答 1:

这里有两种不同的情况: 错误消息( 它们实际上来自 python,而不是 awk ) 和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 1,则没有错误,因为睡眠没有关闭管道结束,直到 python 完成写入。 你的结果可能会有所不同,具体取决于所涉及的计时。

现在,对于 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("%dn", argc);//print the number of arguments we've received


 return 0;//exit successfully


}



因为程序名总是自动传递,并且没有额外的参数,所以运行这个程序将会打印出。 以 example'' 或者 example SomethingGoesHere 运行程序将打印 2,因为有程序名,或者是空白参数或者 SomethingGoesHere

由于awk至少需要 2个参数( 它的名字和其他东西),所以没有任何参数可以自己调用-。

正是因为这个原因,你能够正确地对参数进行。 if程序总是需要 3个参数,但是希望第二个参数为空,你不能简单地忽略它,因为 shell 不知道这个参数会被忽略,程序会出错。



BASE  spec  DIFF  argument  AWK  
相关文章