1

使用scprsync我经常无法处理“参数列表太长”错误。必须使用mvorrm时,我使用起来没有问题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

4

3 回答 3

2

更新后编辑:

find "/Path/to" -maxdepth 1 -name "B*" -exec scp {} Me@137.92.4.152:/Path/to/ \;
于 2017-06-09T16:07:25.753 回答
2

R. Saban 的有用答案解决了您的主要问题:

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

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

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

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

  • Whilefind-exec主要允许使用终止符+代替;(必须作为';'\;防止shell解释;为命令终止符)来传递尽可能多的文件名,以适合单个命令行(内置的xargs,以某种方式说起来),这不是一个选项,因为使用+要求占位符{}在命令行的最后,紧接在+.

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

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

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

于 2017-06-10T01:41:37.433 回答
0

不需要多个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从 stdin ( -T -) 中读取其文件列表,将列表视为空终止 ( --null) 并创建一个新的存档 ( -c)。默认情况下,tar将写入标准输出。

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

于 2017-06-09T16:43:37.323 回答