我在 UNIX 的一个目录下有数百个 PDF。 PDF 的名称非常长(大约 60 个字符)。
当我尝试使用以下命令一起删除所有 PDF 时:
rm -f *.pdf
我收到以下错误:
/bin/rm: cannot execute [Argument list too long]
这个错误的解决方案是什么? mv
和 cp
命令是否也会出现此错误?如果是,如何解决这些命令?
原文由 Vicky 发布,翻译遵循 CC BY-SA 4.0 许可协议
我在 UNIX 的一个目录下有数百个 PDF。 PDF 的名称非常长(大约 60 个字符)。
当我尝试使用以下命令一起删除所有 PDF 时:
rm -f *.pdf
我收到以下错误:
/bin/rm: cannot execute [Argument list too long]
这个错误的解决方案是什么? mv
和 cp
命令是否也会出现此错误?如果是,如何解决这些命令?
原文由 Vicky 发布,翻译遵循 CC BY-SA 4.0 许可协议
这是对命令行参数大小的内核限制。改用 for
循环。
这是一个系统问题,与 execve
和 ARG_MAX
常量有关。有很多关于这方面的文档(参见 man execve 、 debian 的 wiki 、 ARG_MAX details )。
基本上,扩展会产生一个超过 ARG_MAX
限制的 _命令_(及其参数)。在内核 2.6.23
上,限制设置为 128 kB
。此常量已增加,您可以通过执行以下操作来获取其值:
getconf ARG_MAX
# 2097152 # on 3.5.0-40-generic
for
循环使用 for
循环,因为它在 BashFAQ/095 上被推荐并且除了 RAM/内存空间之外没有限制:
试运行以确定它将删除您期望的内容:
for f in *.pdf; do echo rm "$f"; done
并执行它:
for f in *.pdf; do rm "$f"; done
这也是一种可移植的方法,因为 glob 在 shell 之间具有强大且一致的行为( POSIX 规范的一部分)。
注意: 正如几条评论所指出的,这确实更慢但更易于维护,因为它可以适应更复杂的场景, _例如_,人们想要做的不仅仅是一个动作。
find
如果你坚持,你可以使用 find
但真的 不要使用 xargs 因为它 “在读取非 NUL 分隔的输入时很危险(损坏、可利用等)” :
find . -maxdepth 1 -name '*.pdf' -delete
使用 -maxdepth 1 ... -delete
而不是 -exec rm {} +
允许 find
在不使用外部进程的情况下简单地执行所需的系统调用,因此速度更快(感谢 @chepner 评论)。
原文由 Édouard Lopez 发布,翻译遵循 CC BY-SA 4.0 许可协议
7 回答5.3k 阅读
4 回答4k 阅读
2 回答5.9k 阅读✓ 已解决
2 回答2.5k 阅读✓ 已解决
1 回答2.3k 阅读✓ 已解决
2 回答795 阅读✓ 已解决
2 回答3.2k 阅读
发生这种情况的原因是因为 bash 实际上将星号扩展到每个匹配的文件,从而产生了很长的命令行。
尝试这个:
警告: 这是一个递归搜索,也会在子目录中查找(并删除)文件。仅当您确定不想确认时,才将
-f
添加到 rm 命令。您可以执行以下操作以使命令非递归:
另一种选择是使用 find 的
-delete
标志: