复制大量文件时出现“参数列表太长”错误

复制大量文件时出现“参数列表太长”错误

我正在使用以下命令:

\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: 参数列表太长

有任何想法吗?

答案1

*.jpg 扩展为一个比 shell 可以处理的长度更长的列表。请尝试以下方法

find  /home/ftpuser/public_html/ftparea/ -name "*.jpg" -exec cp -uf "{}" /your/destination \;

答案2

系统命令的参数列表长度有一个最大限制 —— 此限制是基于MAX_ARG_PAGES内核编译时的值的特定于发行版的,并且如果不重新编译内核就无法更改。

由于 shell 处理通配符的方式,当您使用相同的参数(“*.jpg”)时,这将影响大多数系统命令。由于通配符首先由 shell 处理,然后发送给命令,因此命令:

cp -uf *.jpg /targetdir/

与 shell 中编写的代码基本相同:

cp -uf 1.jpg 2.jpg ... n-1.jpg n.jpg /targetdir/

如果你要处理大量的 jpeg,那么很快就会变得难以管理。根据你的命名约定和实际需要处理的文件数量,你可以运行cp一次对目录的不同子集执行命令:

cp -uf /sourcedir/[a-m]*.jpg /targetdir/
cp -uf /sourcedir/[n-z]*.jpg /targetdir/

这可能会起作用,但具体效果取决于您能多好地将文件列表分解为方便的可全局块。

Globbable。我喜欢这个词。

一些命令,例如寻找参数,可以处理大型文件列表,而不需要制作大小合适的参数列表。

find /sourcedir/ -name '*.jpg' -exec cp -uf {} /targetdir/ \;

-exec 参数将对找到的每个文件运行一次命令行的其余部分寻找,用找到的每个文件名替换 {}。由于cp命令一次只能对一个文件运行,参数列表限制不是问题。

由于必须单独处理每个文件,因此这可能会很慢。使用参数可以提供更有效的解决方案:

find /sourcedir/ -name '*.jpg' -print0 | xargs -0 cp -uf -t /destdir/

参数可以获取提供的完整文件列表寻找,并将其分解为可管理大小的参数列表并运行cp在每个子列表上。

当然,也可以重新编译内核,为 设定一个更大的值MAX_ARG_PAGES。但是重新编译内核的工作量比我愿意在这个答案中解释的要大。

答案3

发生这种情况是因为您的通配符表达式(*.jpg)在扩展时超出了命令行参数的长度限制(可能是因为您下有很多 .jpg 文件/home/ftpuser/public_html/ftparea)。

有几种方法可以绕过这个限制,比如使用findxargs。看看本文了解有关如何执行此操作的更多详细信息。

答案4

程序可以指定的参数数量是有上限的,bash 会将 *.jpg 扩展为许多 cp 参数。您可以使用 find、xargs 或 rsync 等来解决此问题。

看看这里关于 xargs 和 find

https://stackoverflow.com/questions/143171/how-can-i-use-xargs-to-copy-files-that-have-spaces-and-quotes-in-their-names

相关内容