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

ice*_*ard 12 linux bash unix-shell

我正在使用以下命令:

\cp -uf /home/ftpuser1/public_html/ftparea/*.jpg /home/ftpuser2/public_html/ftparea/
Run Code Online (Sandbox Code Playgroud)

我收到错误:

-bash: /bin/cp: Argument list too long
Run Code Online (Sandbox Code Playgroud)

我也试过:

ls /home/ftpuser1/public_html/ftparea/*.jpg | xargs -I {} cp -uf {} /home/ftpuser2/public_html/ftparea/
Run Code Online (Sandbox Code Playgroud)

还是有 -bash: /bin/ls: 参数列表太长

有任何想法吗?

Sha*_*hin 19

*.jpg 扩展到一个比 shell 可以处理的更长的列表。试试这个

find  /home/ftpuser/public_html/ftparea/ -name "*.jpg" -exec cp -uf "{}" /your/destination \;
Run Code Online (Sandbox Code Playgroud)


gol*_*udo 6

系统命令的参数列表的长度有一个最大限制——这个限制是特定于发行版的,基于MAX_ARG_PAGES内核编译时的值,并且不能在不重新编译内核的情况下更改。

由于 shell 处理 globbing 的方式,当您使用相同的参数 ("*.jpg") 时,这将影响大多数系统命令。由于glob先由shell处理,然后再发送给命令,命令:

cp -uf *.jpg /targetdir/
Run Code Online (Sandbox Code Playgroud)

与 shell 基本相同,就像你写的一样:

cp -uf 1.jpg 2.jpg ... n-1.jpg n.jpg /targetdir/
Run Code Online (Sandbox Code Playgroud)

如果您正在处理大量 jpeg,这可能会很快变得难以管理。根据您的命名约定和您实际需要处理的文件数量,您可以一次在目录的不同子集上运行cp命令:

cp -uf /sourcedir/[a-m]*.jpg /targetdir/
cp -uf /sourcedir/[n-z]*.jpg /targetdir/
Run Code Online (Sandbox Code Playgroud)

这可以工作,但它到底有多有效取决于您将文件列表分解为方便的可全局块的能力。

通俗易懂。我喜欢这个词。

某些命令,例如findxargs,可以处理大文件列表,而无需制作过大的参数列表。

find /sourcedir/ -name '*.jpg' -exec cp -uf {} /targetdir/ \;
Run Code Online (Sandbox Code Playgroud)

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

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

find /sourcedir/ -name '*.jpg' -print0 | xargs -0 cp -uf -t /destdir/
Run Code Online (Sandbox Code Playgroud)

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

当然,也有可能只是重新编译内核,为MAX_ARG_PAGES. 但是重新编译内核比我愿意在这个答案中解释的工作要多。