【问题标题】:how much should I worry about argument list too long?我应该多担心参数列表太长?
【发布时间】:2011-08-12 08:41:52
【问题描述】:

我有一个 shell 脚本,它会使用一些 * 来做通配符。例如:

mv /someplace/*.DAT /someotherplace

for file in /someplace/*.DAT
do 
  echo $file
done

然后当我想到错误处理时,我担心 infamuse argument list too long 错误。

我应该担心多少?贝壳究竟能撑多久?例如,它会在 500 个文件或 1000 个文件时死掉吗?是否取决于文件名的长度?

编辑: 我发现参数 max 是 131072 字节。我不是在寻找解决方案来克服争论太长的问题。我真正需要的是——它转换为普通字符串命令需要多长时间?即:该命令有多“长”?它算空间吗?

【问题讨论】:

  • 您忘记将$file 括在"" 中。最好使用"$file"

标签: bash


【解决方案1】:

原谅我的无知

如果我没记错的话,数据上限为 32Kb

第一个命令

find /someplace -name '*.DAT' -print0 | xargs -r0 mv --target='/someotherplace'

第二条命令

find /someplace -type f -name "*.DAT"

【讨论】:

  • 该命令可以通过管道传送到while read line 以对每个文件执行循环,从而允许您将单个(可溢出)mv 命令替换为(安全)mv 循环。 (当然,这种技术适用于命令可能像这样溢出的任何类似情况。)
  • 使用read一次获取一个文件与for-循环glob并没有太大区别,但与glob for-loops不同,它甚至不是从标准输入解析文件名的安全方法除非您使用支持使用空字符作为read 分隔符的非POSIX shell。 find -print0 | xargs -0 更好,因为它既安全又安全,xargs 会自动拆分参数列表以使其保持在最大长度以下,从而减少产生的 mv 进程和更快的整体操作。
【解决方案2】:

是的,这取决于文件名长度。命令行最大值是单个硬编码限制,因此长文件名会更快地耗尽它。而且这通常是内核限制,因此在 bash 中无法绕过它。是的,这很严重:很少发生的错误总是比明显的错误更严重,因为质量保证可能会错过它们,而且当它们确实发生时,几乎可以保证是一个噩梦般的不可读的命令行,你不能甚至可以正确重建!

出于所有这些原因:现在而不是以后处理问题。

【讨论】:

    【解决方案3】:

    是否

    您应该担心多少?您不妨问“我的代码的生命周期是多少?”

    我会敦促您始终担心参数列表限制。此限制是在编译时设置的,并且在不同的系统、shell 等上很容易有所不同。您确定您的代码将始终在其原始环境中以预期的输入和该环境的原始限制运行吗?

    如果 glob 的扩展可能导致未知数量的文件扩展未知长度的文件该扩展可能会超过将在在任何未知的未来环境中生效,那么您应该从第一天开始编写代码以避免此错误。

    如何

    对于这个问题,有三个基于find 的解决方案。经典方案使用xargs

    find ... | xargs command
    

    xargs 将执行 command 并尽可能多地匹配而不会溢出参数列表,然后根据需要重复该调用,直到 find 没有更多结果。

    此解决方案存在问题,因为文件名可能包含换行符。如果你幸运的话,你有一个更好的 find 版本,它支持带有 -print0 的空终止文件名,你可以使用更安全的解决方案

    find ... -print0 | xargs -0 command
    

    这与第一个 find 相同,但它对所有合法文件名都是安全的。

    较新版本的find 可能支持带有+ 终止符的-exec,这允许另一种解决方案

    find ... -exec command {} +
    

    这在功能上与上面的第二个find 命令相同:对所有文件名都是安全的,将command 的调用拆分为不会溢出参数列表的块。我更喜欢这种形式,如果有的话。

    【讨论】:

    • 我的同事告诉我他可以毫无问题地 mv 600 个文件。所以我真的很想知道我是否需要关心这样的问题。 1000+ 个文件很少见,最多 2000 个文件。
    • @gunbuster363:问题在于它不是文件数,而是字节数。正如 Kilian Foth 指出的那样,名称较长的文件将导致更少的文件更快地达到限制。如果您始终知道输入的总字节数不会超过当前和所有未来系统的参数列表限制,请务必忽略该问题。就个人而言,我宁愿拥有我知道将来不会破坏的代码。
    猜你喜欢
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 2022-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多