Python'sys.argv'是否限制了最大参数数量?

时间:2012-02-01 20:40:24

标签: python xargs argparse argv

我有一个需要处理大量文件的Python脚本。为了解决Linux对可以传递给命令的参数数量的相对较小的限制,我将find -print0xargs -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

但是看起来xargs或者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 '1810,1830p' filelist显示上述示例的一些奇怪之处。是什么给了什么?

我差点忘了:

$ python -V
Python 2.7.2+

5 个答案:

答案 0 :(得分:7)

默认情况下,

xargs将填充您的参数。请查看--max-args的{​​{1}}和--max-chars选项。其手册页还解释了限制(在xargs下)。

答案 1 :(得分:3)

find提供了os.walk所需的所有内容。

不要将find和shell用于其中任何一项。

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

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

答案 2 :(得分:2)

Python似乎没有限制参数的数量,但操作系统却有限制。

查看here进行更全面的讨论。

答案 3 :(得分:1)

xargs会尽可能多地通过,但仍然存在限制。例如,

find ~/ -name "*" -print0 | xargs -0 wc -l | grep total

会给你多行输出。

您可能希望让脚本获取包含文件名列表的文件,或者在其标准输入列表中接受文件名。

答案 4 :(得分:0)

问题是 xargs is limited 由调用参数的字符数决定(最多 2091281)。

快速测试表明,这范围从 5000 个文件到 55000 个文件,具体取决于路径的长度。

获得更多的解决方案是通过标准输入接受文件路径中的管道。

find ... -print0 | script.py

#!/usr/bin/env python3

import sys

files = sys.stdin.read().split('\0')
...