Bash: 无法使用 find -exec

Bash: Fail to use find -exec

当使用scprsync时,我经常无法处理'Argument list too long'错误。当必须 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

更新后编辑:

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

一个不需要多个 scp 连接(因此密码输入)的解决方案是在一侧 tar 而在另一侧 untar 像:

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 ) 并创建一个新存档 (-c)。默认情况下,tar 将写入标准输出。

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

解决了您的主要问题:

  • -name 只接受 文件名 模式,不接受 路径图案.

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

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

  • 作为替代方案,考虑完全绕过 scp 的使用,如 .

  • 中所建议
  • 虽然 find-exec 主要允许使用终止符 + 代替 ;(必须作为 ';'\; 以防止 shell; 解释为命令终止符)用于传递适合单个命令行的尽可能多的文件名(从某种意义上说,内置 xargs),这不是一个选项,因为使用 + 需要占位符 {}last 在命令行上,紧接在 +.

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

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

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