在操作大量文件的时候,会遇到“Argument list too long.”(参数列表过长)的错误,这个错误是从哪儿来的呢?
其实这个错误由系统调用exec()产生的,当它的参数过长时,就会返回E2BIG的错误,然后shell就会把这个错误返回。
E2BIG一般在sys/errno.h里面定义:
#define E2BIG 7
网上有人说这是shell的限制,其实shell并没有参与这个限制,它只是负责参数的传递,也同样负责错误的传递。
这个参数列表的限制到底是多少呢?可以有两个地方看:
1、getconf ARG_MAX命令
%getconf ARG_MAX
262144
2、sysctl:
%sysctl -a | grep argmax
kern.argmax: 262144
可以看到,FreeBSD下默认是262144
数值有了,那这个数值是指参数的个数还是参数的总长度?单位是字节还是位,或者是其它的东东?
我们来做个实验,我准备了近七千个文件:
/web/upload % ls | wc
6926 6926 263188
/web/upload % ls *
/sbin/ls: Argument list too long.
/web/upload % rm scrsht_0032_201001_20140*
/web/upload % ls | wc
6863 6863 260794
/web/upload/0045 % ls *
eclass_0043_20140508095200.xml
eclass_0094_20140504081735.xml
eclass_0043_20140508095925.xml
……
注意结果中,第一字段是行数,也就是文件数;第二字段是单词数,由于文件名中间没有空格,所以每一行就相当于一个单词;最后一个字段是字符数,单位是字节。
从结果上我们可以看出,当所有文件名列表的字节数大于262144的时候,则会显示“参数列���过长”,低于262144,则会��示正常,当然只是大致的数字,因为命令本身还要有其他的一些字符在里面。
由此我们可以判断,这个262144的单位是字节,指的是整个命令的长度。
那这个数字从哪儿来的呢?再祭器find神器,就会找到位置:
find /usr/src –name “*.h” –exec grep ARG_MAX –nH {} \;
……
/sys/sys/syslimits.h:49:#define ARG_MAX 262144
……
该头文件明确指出,262144单位是字节,是供exec()系统函数准备的。
至此,真相大白了,如果你觉得262144有点小,那么可以加大一些,注意别加的太大了,超出内存限制就麻烦了,不过个人感觉,凭现在的动辄数十个G的内存,加到10M应该问题不大,加到10M的话,每个文件按40个字节算,可以支持262144个,也就是25万个文件,一般应用应该可以了。
另外,还有个参数是值得关心的,就是sysconf(_SC_ARG_MAX),不过大多数系统中,都随ARG_MAX了。
该贴被wulcan编辑于2014-5-30 9:13:57该贴由hui.chen转至本版2014-11-5 17:04:59