我正在使用以下命令:
\cp -uf /home/ftpuser1/public_html/ftparea/*.jpg /home/ftpuser2/public_html/ftparea/
我得到了错误:
-bash: /bin/cp: Argument list too long
我也试过:
ls /home/ftpuser1/public_html/ftparea/*.jpg | xargs -I {} cp -uf {} /home/ftpuser2/public_html/ftparea/
仍然得到 -bash: /bin/ls: Argument list too long
有任何想法吗?
*.jpg 扩展为一个比 shell 可以处理的列表更长的列表。试试这个
系统命令的参数列表的长度有一个最大限制——这个限制是特定于发行版的,基于
MAX_ARG_PAGES
编译内核时的值,并且在不重新编译内核的情况下无法更改。由于 shell 处理 globbing 的方式,当您使用相同的参数 ("*.jpg") 时,这将影响大多数系统命令。由于 glob 先由 shell 处理,然后发送到命令,命令:
与 shell 基本相同,就好像你写的一样:
如果您正在处理大量的 jpeg,这可能会很快变得难以管理。根据您的命名约定和实际必须处理的文件数量,您可以一次在目录的不同子集上运行cp命令:
这可能会奏效,但具体效果如何取决于您将文件列表分解为方便的全局块的程度。
全局的。我喜欢这个词。
一些命令,例如find和xargs,可以处理大型文件列表,而不会产生痛苦大小的参数列表。
-exec 参数将为 find 找到的每个文件运行一次命令行的其余部分,将 {} 替换为找到的每个文件名。由于cp命令一次只在一个文件上运行,因此参数列表限制不是问题。
由于必须单独处理每个文件,这可能会很慢。使用xargs可以提供更有效的解决方案:
xargs可以获取find提供的完整文件列表,并将其分解为可管理大小的参数列表,并在每个子列表上运行cp。
当然,也有可能只重新编译内核,为
MAX_ARG_PAGES
. 但是重新编译内核的工作比我愿意在这个答案中解释的要多。发生这种情况是因为您的通配符表达式 (
*.jpg
) 在展开时超出了命令行参数长度限制(可能是因为您在 .jpg 下有很多文件/home/ftpuser/public_html/ftparea
)。有几种方法可以绕过该限制,例如使用
find
orxargs
。请查看这篇文章以了解有关如何执行此操作的更多详细信息。正如 GoldPseudo 评论的那样,您可以将多少个参数传递给您正在生成的进程。有关该参数的详细描述,请参阅他的答案。
您可以通过不向进程传递太多参数或减少传递的参数数量来避免该问题。
shell 中的 for 循环、find 和 ls、grep 和 while 循环在这种情况下都做同样的事情——
和
和
它们都有一个读取目录的程序(shell 本身、find 和 ls)和一个不同的程序,它每次执行实际上接受一个参数并遍历整个命令列表。
现在,这会很慢,因为 rm 需要为每个匹配 *.jpg 模式的文件分叉和执行。
这就是 xargs 发挥作用的地方。xargs 接受标准输入,对于每 N 行(对于 freebsd,默认为 5000)行,它会生成一个带有 N 个参数的程序。xargs 是对上述循环的优化,因为您只需要 fork 1/N 程序来迭代从命令行读取参数的整个文件集。
可以为程序指定最大数量的参数,bash 将 *.jpg 扩展为 cp 的许多参数。您可以使用 find、xargs 或 rsync 等来解决它。
在这里查看有关 xargs 并找到
https://stackoverflow.com/questions/143171/how-can-i-use-xargs-to-copy-files-that-have-spaces-and-quotes-in-their-names
'*' glob 扩展到太多文件名。请改用 find /home/ftpuser/public_html -name '*.jpg' 。
听起来您在该目录中有太多
*.jpg
文件,无法一次将它们全部放在命令行上。你可以试试:您可能需要检查
man xargs
您的实现以查看该-I
开关是否适合您的系统。实际上,您真的打算将这些文件复制到它们已经存在的相同位置吗?
使用
+
选项find -exec
将大大加快操作。该
+
选项需要{}
是最后一个参数,因此使用-t /your/destination
(or--target-directory=/your/destination
) 选项cp
使其工作。来自
man find
:编辑:重新排列 cp 的参数
转到文件夹
并执行以下操作:
这样,如果文件夹 'ftparea' 有子文件夹,如果你只想要其中的 '*.jpg' 文件,这可能会产生负面影响,但如果没有任何子文件夹,这种方法肯定会比使用 find 和 xargs