是Python';sys.argv';参数的最大数量有限吗?

是Python';sys.argv';参数的最大数量有限吗?,python,xargs,argparse,argv,Python,Xargs,Argparse,Argv,我有一个需要处理大量文件的Python脚本。为了绕过Linux对可以传递给命令的参数数量的相对较小的限制,我使用find-print0和xargs-0 我知道另一种选择是使用Python的glob模块,但当我有一个更高级的find命令、查找修改时间等时,这不会有帮助 在大量文件上运行我的脚本时,Python只接受参数的子集,我最初认为这是argparse中的一个限制,但似乎是在sys.argv中。我找不到这方面的任何文件。是虫子吗 下面是一个示例Python脚本,说明了这一点: import a

我有一个需要处理大量文件的Python脚本。为了绕过Linux对可以传递给命令的参数数量的相对较小的限制,我使用
find-print0
xargs-0

我知道另一种选择是使用Python的glob模块,但当我有一个更高级的
find
命令、查找修改时间等时,这不会有帮助

在大量文件上运行我的脚本时,Python只接受参数的子集,我最初认为这是
argparse
中的一个限制,但似乎是在
sys.argv
中。我找不到这方面的任何文件。是虫子吗

下面是一个示例Python脚本,说明了这一点:

import argparse
import sys
import os

parser = argparse.ArgumentParser()
parser.add_argument('input_files', nargs='+')
args = parser.parse_args(sys.argv[1:])

print 'pid:', os.getpid(), 'argv files', len(sys.argv[1:]), 'argparse files:', len(args.input_files)
我有很多文件可以运行此操作:

$ find ~/ -name "*" -print0 | xargs -0 ls > filelist
748709 filelist
但它似乎是Python正在将我的大文件列表分块,并通过几个不同的Python运行来处理它:

$ find ~/ -name "*" -print0 | xargs -0 python test.py
pid: 4216 argv files 1819 number of files: 1819
pid: 4217 argv files 1845 number of files: 1845
pid: 4218 argv files 1845 number of files: 1845
pid: 4219 argv files 1845 number of files: 1845
pid: 4220 argv files 1845 number of files: 1845
pid: 4221 argv files 1845 number of files: 1845
...
为什么要创建多个进程来处理列表?为什么它会被分块?我认为文件名中没有换行符,
-print0
-0
不应该处理这个问题吗?如果有换行符,我希望
sed-n'18101830p'文件列表
对上述示例显示出一些奇怪之处。有什么好处

我差点忘了:

$ python -V
Python 2.7.2+

Python似乎没有对参数的数量设置限制,但操作系统设置了


查看更全面的讨论。

xargs将尽可能多地通过,但仍有限制。比如说,

find ~/ -name "*" -print0 | xargs -0 wc -l | grep total
将为您提供多行输出


您可能希望让脚本获取包含文件名列表的文件,或者在其stdin上接受文件名。

xargs
默认情况下会将参数分块。查看
xargs
--max args
--max chars
选项。其手册页还解释了限制(在
--max chars
下)。

您想要从
查找
中获得的所有内容都可以从
操作系统中获得。walk

不要使用
find
和shell来执行任何操作

使用
os.walk
并用Python编写所有规则和过滤器


“查找修改时间”意味着您将使用
os.stat
或类似的库函数

奇怪的问题。作为另一个选项,您当然可以在脚本中解析
filelist
。xargs所做的可能是重复的。它仍然需要通过shell调用Python,因此在参数上也有相同的限制。为什么不让Python程序直接使用
~/
-name*
参数呢?我原以为xargs可以神奇地绕过有限的参数空间问题。事实证明,它只是用更小的块来分叉一个单独的进程。我还发现,这种行为在我使用xargs的每个应用程序中都没有区别,除了这一个……我原则上同意,在python中使用os.walk、glob.glob和os.stat完成所有这些都是可行的。我不知道的是xargs仍然遵守操作系统的限制,只是用剩余的参数多次调用命令。“原则上同意”表示“不同意”。然而,你没有提供任何理由。以下是你的决定完全是建议的原因。所有Python都更快、更简单、更灵活。更简单,因为它是一种语言:Python。更快,因为它在单个进程中运行(无需交换)。如果您想提高速度,请使用
多处理
。最后,它更灵活,因为您不受
find
的奇怪限制的约束。简化应用程序并没有坏处。应用程序通常不需要处理数千个文件。工作通常在几十个文件(染色体)上完成;在我正在测试的特定基准测试中,我有数千个文件。也许我的OP没有说清楚。@JakeBiesinger:也许我的评论没有说清楚,如果你处理一个或数百万个文件,那么
find
仍然是个坏主意。我不想重复这些原因,而是在结束时说,用Python替换基于
find
的shell脚本没有坏处。没有坏处。很多优点,谢谢。我以前没见过这个。你知道为什么上面的命令
find~/-name“*”-print0 | xargs-0ls>filelist
实际有效吗?似乎会多次调用
ls
,所有调用都会写入(而不是追加!)同一个文件。也许文件只打开一次,而我们捕获的是xargs的输出?shell负责重定向
ls
实际输出到
stdout
。把它想象成括号内的行上的所有内容和括号外的重定向。