python 中如何解决命令行参数列表过长

作者: , 共 947 字

最近遇到的一个问题,我们有一个 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.

在两步路上, windy 图层基于 openstreetmap ,很好用。大家一定要加上(两步路的图源( OCM、Windy 和 Google 地形图层)。方法:在两步路地图界面,图层选择里点大+号,然后扫下面二维码即可: