scp 与 gnu parallel 一起使用时不显示输出

scp 与 gnu parallel 一起使用时不显示输出

我有一个简短的脚本,用于scp将文件复制到许多远程主机(是的,我知道rdistrsync;它们都无法为一些主机工作 - 这不是这里的重点;我只是复制一些非-无论如何都是关键文件)。

脚本的内容看起来像这样:

for h in $HOSTS; do
    echo $h
    echo '----------------------------------------'
    scp -r $FILES ${h}:
    echo ''
done

以下是运行此脚本的部分输出:

protector
----------------------------------------
.bash_profile                                                                                                                100%  555     0.5KB/s   00:00    
.bashrc                                                                                                                      100% 2124     2.1KB/s   00:00    
.zshenv                                                                                                                      100%  561     0.6KB/s   00:00    
.zshrc                                                                                                                       100% 2354     2.3KB/s   00:00    
.shrc                                                                                                                        100% 1887     1.8KB/s   00:00    
.bash_logout                                                                                                                 100%   17     0.0KB/s   00:00    
.logout                                                                                                                      100%   64     0.1KB/s   00:00    
.zlogout                                                                                                                     100%   17     0.0KB/s   00:00    
.vimrc                                                                                                                       100%  717     0.7KB/s   00:00    

pup
----------------------------------------
.bash_profile                                                                                                                100%  555     0.5KB/s   00:00    
.bashrc                                                                                                                      100% 2124     2.1KB/s   00:00    
.zshenv                                                                                                                      100%  561     0.6KB/s   00:00    
.zshrc                                                                                                                       100% 2354     2.3KB/s   00:00    
.shrc                                                                                                                        100% 1887     1.8KB/s   00:00    
.bash_logout                                                                                                                 100%   17     0.0KB/s   00:00    
.logout                                                                                                                      100%   64     0.1KB/s   00:00    
.zlogout                                                                                                                     100%   17     0.0KB/s   00:00      
.vimrc                                                                                                                       100%  717     0.7KB/s   00:00    

由于这个脚本复制到数百台主机,需要一点时间,所以我决定尝试使用GNU 并行以加快速度。这是使用的脚本的修订版本parallel(请不要在开始时评论echohack,它与问题无关):

(for host in $(echo $HOSTS); do echo $host; done) | parallel "echo {}; echo '----------------------------------------' ; scp -r $FILES {}: ; echo ''"

问题是,以这种方式使用的输出scp如下所示:

pup
----------------------------------------

soils
----------------------------------------

因为命令是并行运行的,所以顺序不同,并行似乎比 scps 的 for 循环完成得快得多,但正如您所看到的,scp 没有输出到 stdout。我不明白为什么 - 例如,从 echo 到标准输出的输出没有被抑制。当我尝试scp -v内部并行时,我得到部分详细输出,但我没有得到任何通常的大小/时间信息。

有人知道为什么 scp 输出被抑制吗?

答案1

要欺骗scp认为它已tty连接,您可以使用script

script -c 'scp foo server1:/bar/'

因此,要运行它,parallel您需要类似的东西:

parallel -j30 "echo {}; echo '----------------------------------------' ; script -c 'scp -r $FILES {}:' ; echo ''"   ::: $HOSTS

要了解更多信息,请观看介绍视频(https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1),示例 (n1_argument_appending">http://www.gnu.org/software/parallel/man.html#example__working_as_xargs_n1_argument_appending)和教程(http://www.gnu.org/software/parallel/parallel_tutorial.html)。

答案2

这似乎对我有用:

#!/bin/sh

for h in $(cat /tmp/servers);
do
    for f in $(cat /tmp/files);
    do
        echo $h
        echo '----------------------'
        parallel -vv "scp root@$h:$f /tmp"
    done
done

取出 -vv 以删除详细输出。当然,对其进行修改,以便 A) 它使用您的 $HOSTS 和 $FILES 变量,B) 它复制到远程服务器而不是从远程服务器复制。

相关内容