最近遇到的一个问题,我们有一个 C++程序(假设就叫做 calc吧),可以接受很多个文件路径,来计算某个东西:
calc file1 file2 file3
在 Python 里我们可以如下调用:
proc = subproccess.Popen("calc file1 file2 file3 ...", shell=True)
当文件太多时,就报错了:
OSError:[Errno 7] Argument list too long: /bin/sh
其实换成下面的形式就好了:
proc = subproccess.Popen(["calc"] + files_list, shell=False)
这个问题的根源在于,系统的单个参数一般是系统页面大小的 32 倍,一般是131072,这可以执行 xargs --show-limits得到:
Your environment variables take up 4735 bytes
POSIX upper limit on argument length (this system): 2090369
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2085634
Size of command buffer we are actually using: 131072
Maximum parallelism (--max-procs must be no greater): 2147483647
如果 Popen 将整个"calc file1 file2 file3 ..."传入,那整个长度就受到 131072 长度的限制。但如果将每个参数分拆成数组传入,那每个子参数不要超过 131072 即可。
那拆分后,是不是可以无限长了呢?那也不行。参数总长度不能超过ARG_MAX,下面命令可以查询该配置项,一般是 2097152 。
getconf ARG_MAX
Q. E. D.