使用 xargs 向 scp 提供参数

使用 xargs 向 scp 提供参数

当我跑步时svn st | awk '{print $2}',我得到:

a.py
b.py
c.py

然后我想将scp这些文件发送到远程服务器。我努力了:

svn st | awk '{print $2}' | xargs scp my_name@my_server:~/

但这不起作用。执行此操作的正确命令是什么?

谢谢你!

答案1

尝试这个。应该与最新版本的 xargs 一起使用。

svn st | awk '{print $2}' | xargs -iz scp z my_name@my_server:

或者,您可以循环浏览文件。

for file in $(svn st | awk '{print $2}'); do scp $file my_name@my_server: ; done

答案2

这不起作用的原因是你告诉xargs运行

scp my_name@my_server:~/ a.py b.py c.py

参数的顺序与您想要执行的操作不符。一种解决方案是强制文件名出现在命令行上的目标之前。这需要 GNU xargs(即 Linux 或 Cygwin)。当我们这样做时,我们可以通过传递-d '\n'来确保任何不包含换行符的文件名都可以工作(如果没有-d, xargs 期望对其输入进行一些奇怪的引用);如果您使用典型的软件源代码树(其中文件名往往非常温和),则没有必要这样做。

svn st | awk '{print $2}' |
xargs -d\\n -I{} scp {} my_name@my_server:~/

此方法的缺点是scp为每个文件单独调用。如果您要复制大量小文件,这可能会产生重大影响,因为建立 SSH 连接需要一些时间。您可以通过使用 SSH 主连接来大大缩短每个连接的时间(这超出了本答案的范围,请参阅手册,尤其是中的ControlMasterControlPath选项.ssh/config)。

强制参数位于正确位置的一种方法是通过中间 shell。这是使用xargsor时对参数重新排序的通用技术find … -exec

svn st | awk '{print $2}' |
xargs -d\\n sh -c 'scp "$@" "$0" my_name@my_server:~/

另一种可能性是使用rsync代替scp.您可以rsync在标准输入上传递文件名列表。由于rsync需要模式列表而不是文件名列表,因此这要求您的文件名不包含任何通配符(具体来说,没有换行符,没有\[*?且没有首字母#;)。

svn st | awk '{print $2}' |
rsync -a --include-from=- --exclude='*' . my_name@my_server:~/

相关内容