【问题标题】:Bash: Fail to use find -execBash:无法使用 find -exec
【发布时间】:2017-11-11 17:32:52
【问题描述】:

当使用scprsync 时,我经常无法处理“参数列表太长”错误。当不得不mvrm 时,我使用findxargs 没有问题,但我不明白如何使用find-exec,尽管所有SE 帖子都关于该主题。考虑以下问题...

我试过了

$scp /Path/to/B* Me@137.92.4.152:/Path/to/

-bash: /usr/bin/scp: Argument list too long

所以我尝试了

$find . -name "/Path/to/B*" -exec scp "{}" Me@137.92.4.152:/Path/to/ '\;'

find: -exec: no terminating ";" or "+"

所以我尝试了

$find . -name "/Path/to/B*" -exec scp "{}" Me@137.92.4.152:/Path/to/ ';'

find: ./.gnupg: Permission denied
find: ./.subversion/auth: Permission denied

所以我尝试了

$sudo find . -name "/Path/to/B*" -exec scp "{}" Me@137.92.4.152:/Path/to/ ';'

输入密码后什么也没有发生

我使用的是 Mac OSX 版本 10.11.3,终端版本 2.6.1

【问题讨论】:

  • 你为什么不直接复制目录,而不是里面的所有文件? “scp - r” 可以完成这项工作
  • 抱歉,我的示例很糟糕,因为我选择了所有文件。我更改了示例以明确表示我不想复制所有文件。我现在通常做的是我mkdirfind ... |xargs mv .. 文件,然后scp -r 目录,mv 文件返回和rm -r 相当愚蠢的目录。

标签: bash macos rsync scp find-util


【解决方案1】:

R. Saban's helpful answer 解决了您的主要问题:

  • -name 只接受 文件名 模式,而不接受 路径 模式。

  • 或者,您可以简单地使用 -path 主节点而不是 -name 主节点。

至于尽可能少地调用scp - 每个都需要默认指定密码:

  • 作为替代方案,请考虑完全绕过 scp 的使用,如 Eric Renouf's helpful answer 中所建议的那样。

  • 虽然find-exec 主允许使用终止符+ 代替;(必须作为';'\; 传递以防止shell em> 来自将; 解释为命令终止符)用于传递尽可能多的文件名以适合单个命令行(内置xargs,在某种意义上),这不是一个选项,因为使用的+ 要求占位符{} 在命令行上最后出现,紧挨在+ 之前。

  • 但是,由于您使用的是 macOS,您可以使用 BSD xarg 的非标准 -J 选项将占位符 anywhere 放置在命令行上,同时仍传递为一次尽可能多的参数(使用 BSD find 的非标准 -print0 选项结合 xargs 的非标准 -0 选项确保所有文件名都按原样传递,即使它们有嵌入的空格,实例):

find . -path "/Path/to/B*" -print0 | xargs -0 -J {} scp {} Me@137.92.4.152:/Path/to/

现在您最多会被提示 几次 次:每批参数都有一个提示,根据需要在观察最大值的同时容纳所有参数。调用次数最少的命令行长度。

【讨论】:

    【解决方案2】:

    更新后编辑:

    find "/Path/to" -maxdepth 1 -name "B*" -exec scp {} Me@137.92.4.152:/Path/to/ \;
    

    【讨论】:

    • 哦...我很傻。只是不必将整个路径放在名称中。我现在必须在每个文件中输入我的密码。您是否也有解决方案?
    • 您可以接受这个答案并为您的新问题打开另一个答案;)
    【解决方案3】:

    不需要多个scp 连接(因此也不需要输入密码)的解决方案是在一侧进行 tar 并在另一侧解压缩,例如:

    find /Path/to -maxdepth 1 -name 'B*' -print0 | tar -c --null -T - | ssh ME@137.92.4.152 tar -x -C /Path/to
    

    假设您的find 版本支持-print0 等。它的工作原理是从find 打印出以空值结尾的文件列表并告诉tar 从标准输入(-T -)读取其文件列表,将列表视为空值终止(--null)并创建一个新存档(@ 987654329@)。默认情况下,tar 将写入标准输出。

    然后我们将通过管道将该存档通过ssh 命令发送到目标主机。这将在其标准输入上读取上一个命令的输出,因此我们将在那里使用tar 将存档提取(-x)到给定目录(-C /Path/to

    【讨论】:

      猜你喜欢
      • 2013-12-07
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多