AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 56068
Accepted
icelizard
icelizard
Asked: 2009-08-20 05:48:38 +0800 CST2009-08-20 05:48:38 +0800 CST 2009-08-20 05:48:38 +0800 CST

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

  • 772

我正在使用以下命令:

\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

有任何想法吗?

linux bash unix-shell
  • 9 9 个回答
  • 38758 Views

9 个回答

  • Voted
  1. Best Answer
    Shawn Chin
    2009-08-20T05:57:16+08:002009-08-20T05:57:16+08:00

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

    find  /home/ftpuser/public_html/ftparea/ -name "*.jpg" -exec cp -uf "{}" /your/destination \;
    
    • 20
  2. goldPseudo
    2009-08-20T05:59:48+08:002009-08-20T05:59:48+08:00

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

    由于 shell 处理 globbing 的方式,当您使用相同的参数 ("*.jpg") 时,这将影响大多数系统命令。由于 glob 先由 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/
    

    这可能会奏效,但具体效果如何取决于您将文件列表分解为方便的全局块的程度。

    全局的。我喜欢这个词。

    一些命令,例如find和xargs,可以处理大型文件列表,而不会产生痛苦大小的参数列表。

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

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

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

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

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

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

    • 6
  3. mfriedman
    2009-08-20T05:59:47+08:002009-08-20T05:59:47+08:00

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

    有几种方法可以绕过该限制,例如使用findor xargs。请查看这篇文章以了解有关如何执行此操作的更多详细信息。

    • 3
  4. chris
    2009-08-20T08:51:56+08:002009-08-20T08:51:56+08:00

    正如 GoldPseudo 评论的那样,您可以将多少个参数传递给您正在生成的进程。有关该参数的详细描述,请参阅他的答案。

    您可以通过不向进程传递太多参数或减少传递的参数数量来避免该问题。

    shell 中的 for 循环、find 和 ls、grep 和 while 循环在这种情况下都做同样的事情——

    for file in /path/to/directory/*.jpg ; 
    do
      rm "$file"
    done
    

    和

    find /path/to/directory/ -name '*.jpg' -exec rm  {} \;
    

    和

    ls /path/to/directory/ | 
      grep "\.jpg$" | 
      while
        read file
      do
        rm "$file"
      done
    

    它们都有一个读取目录的程序(shell 本身、find 和 ls)和一个不同的程序,它每次执行实际上接受一个参数并遍历整个命令列表。

    现在,这会很慢,因为 rm 需要为每个匹配 *.jpg 模式的文件分叉和执行。

    这就是 xargs 发挥作用的地方。xargs 接受标准输入,对于每 N 行(对于 freebsd,默认为 5000)行,它会生成一个带有 N 个参数的程序。xargs 是对上述循环的优化,因为您只需要 fork 1/N 程序来迭代从命令行读取参数的整个文件集。

    • 3
  5. Mattias Wadman
    2009-08-20T05:57:52+08:002009-08-20T05:57:52+08:00

    可以为程序指定最大数量的参数,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

    • 2
  6. William Pursell
    2009-08-20T05:57:22+08:002009-08-20T05:57:22+08:00

    '*' glob 扩展到太多文件名。请改用 find /home/ftpuser/public_html -name '*.jpg' 。

    • 1
  7. Greg Hewgill
    2009-08-20T05:58:06+08:002009-08-20T05:58:06+08:00

    听起来您在该目录中有太多*.jpg文件,无法一次将它们全部放在命令行上。你可以试试:

    find /home/ftpuser/public_html/ftparea1 -name '*.jpg' | xargs -I {} cp -uf {} /home/ftpuser/public_html/ftparea2/
    

    您可能需要检查man xargs您的实现以查看该-I开关是否适合您的系统。

    实际上,您真的打算将这些文件复制到它们已经存在的相同位置吗?

    • 1
  8. Dennis Williamson
    2009-08-20T06:12:40+08:002009-08-20T06:12:40+08:00

    使用+选项find -exec将大大加快操作。

    find  /home/ftpuser/public_html/ftparea/ -name "*jpg" -exec cp -uf -t /your/destination "{}" +
    

    该+选项需要{}是最后一个参数,因此使用-t /your/destination(or --target-directory=/your/destination) 选项cp使其工作。

    来自man find:

    -exec 命令 {} +

              This  variant  of the -exec action runs the specified command on  
              the selected files, but the command line is built  by  appending  
              each  selected file name at the end; the total number of invoca‐  
              tions of the command will  be  much  less  than  the  number  of  
              matched  files.   The command line is built in much the same way  
              that xargs builds its command lines.  Only one instance of  ‘{}’  
              is  allowed  within the command.  The command is executed in the  
              starting directory.
    

    编辑:重新排列 cp 的参数

    • 1
  9. pinpinokio
    2014-04-10T01:09:39+08:002014-04-10T01:09:39+08:00

    转到文件夹

    cd /home/ftpuser1/public_html/
    

    并执行以下操作:

    cp -R ftparea/ /home/ftpuser2/public_html/
    

    这样,如果文件夹 'ftparea' 有子文件夹,如果你只想要其中的 '*.jpg' 文件,这可能会产生负面影响,但如果没有任何子文件夹,这种方法肯定会比使用 find 和 xargs

    • 0

相关问题

  • 多操作系统环境的首选电子邮件客户端

  • 你最喜欢的 Linux 发行版是什么?[关闭]

  • 更改 PHP 的默认配置设置?

  • 保护新的 Ubuntu 服务器 [关闭]

  • (软)Ubuntu 7.10 上的 RAID 6,我应该迁移到 8.10 吗?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    从 IP 地址解析主机名

    • 8 个回答
  • Marko Smith

    如何按大小对 du -h 输出进行排序

    • 30 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    Windows 中执行反向 DNS 查找的命令行实用程序是什么?

    • 14 个回答
  • Marko Smith

    如何检查 Windows 机器上的端口是否被阻塞?

    • 4 个回答
  • Marko Smith

    我应该打开哪个端口以允许远程桌面?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    MikeN 在 Nginx 中,如何在维护子域的同时将所有 http 请求重写为 https? 2009-09-22 06:04:43 +0800 CST
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    0x89 bash中的双方括号和单方括号有什么区别? 2009-08-10 13:11:51 +0800 CST
  • Martin Hope
    kch 如何更改我的私钥密码? 2009-08-06 21:37:57 +0800 CST
  • Martin Hope
    Kyle Brandt IPv4 子网如何工作? 2009-08-05 06:05:31 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve