我有一个shell脚本,它将使用一些*来做通配符。例如:
mv /someplace/*.DAT /someotherplace
和
for file in /someplace/*.DAT
do
echo $file
done
然后当我考虑错误处理时,我担心infamuse参数列表太长的错误。
我应该担心多少?实际上壳有多长时间?例如,它会在500个文件或1000个文件中死掉吗?它取决于文件名的长度吗?
修改: 我发现参数max是131072字节。我不是在寻找解决方案来克服争论太久的问题。我真正需要的是 - 它转换为正常的字符串命令多长时间?即:命令的“长”程度如何?它是否算空间?
答案 0 :(得分:4)
原谅我的无知
如果我没记错的话,上限为32Kb数据
第一个命令
find /someplace -name '*.DAT' -print0 | xargs -r0 mv --target='/someotherplace'
第二个命令
find /someplace -type f -name "*.DAT"
答案 1 :(得分:3)
是的,这取决于文件名长度。命令行最大值是单个硬编码限制,因此长文件名将更快耗尽它。而且它通常是一个内核限制,所以在bash中无法绕过它。是的,这很严重:偶尔出现的错误总是比明显的错误更严重,因为质量保证可能会错过它们,当它们确实发生时,它几乎可以保证是一个噩梦般难以理解的命令行,你不能甚至重建得当!
出于所有这些原因:现在处理问题 而不是以后。
答案 2 :(得分:0)
你应该担心多少?您也可以问“我的代码的生命周期是什么?”
我会敦促你总是担心参数列表限制。此限制在编译时设置,并且可以在不同的系统,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
的调用拆分成不会溢出参数列表的块。我更喜欢这种形式。