Python sys.argv的限制?

14
假设我想像这样运行一个Python脚本: python my_script.py MY_INPUT。在这种情况下,MY_INPUT将被传递给sys.argv[1]问:
  1. MY_INPUT所包含的字符数量是否有限制?

  2. MY_INPUT所包含的字符类型是否有限制?

  3. 关于MY_INPUT,是否还有其他限制?

  4. 更新: 我正在使用Ubuntu Linux 10.04。


3
实际上,MY_INPUT 将会被赋值给 sys.argv[1]。而 sys.argv[0] 则包含了 'my_script.py' - Tom Zych
1
@Tom:谢谢,我已经更正了上面的代码。 - user3262424
3个回答

15

argv 的大小受操作系统限制,并且在不同的操作系统上变化很大。引用自 Linux 的 execve(2) 手册:

Limits on size of arguments and environment
   Most Unix implementations impose some limit on the total size
   of the command-line argument (argv) and environment (envp)
   strings that may be passed to a new program.  POSIX.1 allows an
   implementation to advertise this limit using the ARG_MAX
   constant (either defined in <limits.h> or available at run time
   using the call sysconf(_SC_ARG_MAX)).

   On Linux prior to kernel 2.6.23, the memory used to store the
   environment and argument strings was limited to 32 pages
   (defined by the kernel constant MAX_ARG_PAGES).  On
   architectures with a 4-kB page size, this yields a maximum size
   of 128 kB.

   On kernel 2.6.23 and later, most architectures support a size
   limit derived from the soft RLIMIT_STACK resource limit (see
   getrlimit(2)) that is in force at the time of the execve()
   call.  (Architectures with no memory management unit are
   excepted: they maintain the limit that was in effect before
   kernel 2.6.23.)  This change allows programs to have a much
   larger argument and/or environment list.  For these
   architectures, the total size is limited to 1/4 of the allowed
   stack size.  (Imposing the 1/4-limit ensures that the new
   program always has some stack space.)  Since Linux 2.6.25, the
   kernel places a floor of 32 pages on this size limit, so that,
   even when RLIMIT_STACK is set very low, applications are
   guaranteed to have at least as much argument and environment
   space as was provided by Linux 2.6.23 and earlier.  (This
   guarantee was not provided in Linux 2.6.23 and 2.6.24.)
   Additionally, the limit per string is 32 pages (the kernel
   constant MAX_ARG_STRLEN), and the maximum number of strings is
   0x7FFFFFFF.

谢谢。关于可以输入的字符类型,有什么提示吗?可以输入空格吗?可以输入制表符吗? - user3262424
1
@user540009:可以解析任意字符,但是你的shell可能会将空格解释为参数分隔符;如果不希望出现这种情况,可以用引号括起一个单独的参数:python my_script.py 'This is MY_INPUT as one arg' OtherArg - johnsyweb
@user540009,几乎什么都可以,但是ASCII的NUL字符会终止由argv[]指针数组指向的每个字符串,因此构造包含'\0'字节的参数将需要一些编码和解码的工作。但是,可能有更好的机制来完成您想要做的任何事情 :) - sarnold

3

Python本身不对sys.argv的长度或内容施加任何限制。但是,您的操作系统和/或命令行 shell 一定会有限制。在没有详细考虑您的操作环境的情况下,无法完全回答此问题。


在处理Ubuntu Linux时,您有什么限制的想法吗? - user3262424
请参考以下链接获取有关Linux的答案:https://dev59.com/iEnSa4cB1Zd3GeqPOoa0 - Greg Hewgill
谢谢。那么给定的字符类型是什么?可以包括空格吗? - user3262424
Python对列表有限制;sys.maxsize给出了这个限制。实际上,在你创建一个那么大的列表之前,你会先耗尽内存。 - Martijn Pieters

0

我进行了一个快速测试 squid.py $(find . -name '*.java' | head -n 480) 成功481个,失败了 我向上一个16个字符长的目录,所以每个结果删除了17个字符 ../squid.py $(find . -name '*.java' | head -n 638) 成功了,并且639个失败了。 无论发生了什么,似乎都是由所有参数的总大小决定的。

因此为了测试这个问题,我使用了实用程序wc

find . -name '*.java' | head -n 480 | wc
find . -name '*.java' | head -n 481 | wc

在一个目录下面

find . -name '*.java' | head -n 638 | wc
find . -name '*.java' | head -n 639 | wc

结果

$ find . -name '*.java' | head -n638 | wc
    638     638   32665
$ find . -name '*.java' | head -n639 | wc
    639     639   32705
$ cd ..
$ find . -name '*.java' | head -n480 | wc
    480     480   33328
$ find . -name '*.java' | head -n481 | wc
    481     481   33396

所以它看起来非常接近32K,正如其他评论中所述,这高度依赖于系统。这是在Windows 10上的git bash中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接