提供参数以使用xargs进行scp


10

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

a.py
b.py
c.py

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

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

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

谢谢!

Answers:


10

尝试这个。应该可以与最新版本的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
谢谢蒂姆。我在Google上搜索了很多,找到了解决方案:在询问之前,svn st | awk '{print $2}' | xargs -J % scp % my_name@my_server:~/我应该已经阅读过手册页xargs;)
mitnk 2011年

您的解决方案也可以!但是这里有一个错字,-Iz不是-iz

您正在使用什么操作系统?我-iz在Solaris上使用,并且始终可以使用。感谢您的指导。
蒂姆·肯尼迪

4
POSIX xargs具有-I。AIX(6.1)手册页说过时了-i-I应该使用。Solaris 10(和9)同时具有-i-I

1
啊,我的知识已经过时了!-i从Solaris 2.5 开始,我一直在使用。我的朋友们,变老是一件可悲的事情。:)
蒂姆·肯尼迪

4

这行不通的原因是您要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)。

强制参数正确放置的一种方法是通过中间外壳。这是使用xargs或时对参数重新排序的通用技术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:~/
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.