为什么subprocess.Popen参数长度限制小于操作系统报告的限制?

时间:2015-04-22 15:18:10

标签: python linux python-3.x subprocess command-line-arguments

我在Linux 3.16.0上运行Python 3.4.3。我想使用subprocess.Popen来运行一个带有长单个参数(复杂的Bash调用)的命令,大约200KiB。

根据getconfxargs,这应该在我的范围内:

$ getconf ARG_MAX
2097152
$ xargs --show-limits < /dev/null
Your environment variables take up 3364 bytes
POSIX upper limit on argument length (this system): 2091740
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2088376
Size of command buffer we are actually using: 131072

但是,Python失败的限制很小:

>>> subprocess.Popen('echo %s > /dev/null' % ('a' * (131072-4096)), shell=True, executable='/bin/bash')
<subprocess.Popen object at 0x7f4613b58410>
>>> subprocess.Popen('echo %s > /dev/null' % ('a' * (262144-4096)), shell=True, executable='/bin/bash')
Traceback (most recent call last):
  [...]
OSError: [Errno 7] Argument list too long

请注意,Python限制与&#34;实际使用&#34;大致相同。命令缓冲区xargs报告。这表明xargs在某种程度上足够聪明,可以从较小的限制开始,并根据需要增加它,但Python不是。

问题:

  1. 为什么Python限制小于OS限制2MiB?
  2. 我可以增加Python限制吗?
  3. 如果是这样,怎么样?

2 个答案:

答案 0 :(得分:12)

单个字符串参数的最大大小限制为131072.它与python无关:

MAX_ARG_STRLEN

实际上是unix.stackexchange决定单个字符串的最大大小:

  

作为2.6.23以来的附加限制,一个参数不得长于MAX_ARG_STRLEN(131072)。   如果您生成一个长期调用,例如“使用长参数'生成的sh -c',这可能会变得相关”。   (Xan Lopez和Ralf Wildenhues指出)

请参阅this discussion of ARG_MAX,在“参数数量和一个参数的最大长度”下,以及binfmts.h上的this question

您可以在/* * These are the maximum length and maximum number of strings passed to the * execve() system call. MAX_ARG_STRLEN is essentially random but serves to * prevent the kernel from being unduly impacted by misaddressed pointers. * MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer. */ #define MAX_ARG_STRLEN (PAGE_SIZE * 32) #define MAX_ARG_STRINGS 0x7FFFFFFF ~$ echo $(( $(getconf PAGE_SIZE)*32 )) 131072 中看到它:

131071

您可以传递多个长度为subprocess.check_call(['echo', "a"*131071,"b"*131071], executable='/bin/bash',stdout=open("/dev/null","w")) 的字符串:

<RadioButton IsChecked="{Binding Path=SelectedOption, UpdateSourceTrigger=PropertyChanged}">Option1</RadioButton>
<RadioButton IsChecked="{Binding Path=SelectedOption, UpdateSourceTrigger=PropertyChanged, Converter={v:NotBoolenConverter}}">Option2</RadioButton>

但是单个字符串arg不能超过131071个字节。

答案 1 :(得分:-4)

This其他问题与您的问题类似,但适用于Windows。在该场景中,您可以通过避免使用shell=True选项来绕过任何shell限制。

否则,您可以按照该场景中的subprocess.Popen()提供文件列表,并按照@Aaron Digulla的建议。