【发布时间】:2012-02-24 13:23:45
【问题描述】:
我有一个需要处理大量文件的 Python 脚本。为了绕过 Linux 对可传递给命令的参数数量的相对较小的限制,我将find -print0 与xargs -0 结合使用。
我知道另一种选择是使用 Python 的 glob 模块,但是当我有更高级的 find 命令、查找修改时间等时,这将无济于事。
在大量文件上运行我的脚本时,Python 只接受参数的子集,我最初认为是在 argparse 中的一个限制,但似乎在 sys.argv 中。我找不到任何关于此的文档。是bug吗?
这里有一个示例 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+
【问题讨论】:
-
奇怪的问题。作为另一种选择,您当然可以在脚本中解析
filelist。 -
这就是 xargs 所做的。它仍然需要通过 shell 调用 Python,因此对参数有相同的限制。为什么不让你的 Python 程序直接接受
~/和-name *参数呢? -
我曾认为 xargs 以某种方式神奇地解决了有限参数空间问题。事实证明,它只是用较小的块分叉了一个单独的进程。事实证明,这种行为在我使用 xargs 的每个应用程序中都没有区别,保存这个......
标签: python xargs argparse argv