scp
複数のリモートホストにファイルをコピーする短いスクリプトがあります(はい、わかっています。rdist
一部rsync
のホストではすべて機能しません。ここではそれは重要ではありません。とにかく重要ではないファイルのみをコピーします)。
スクリプトの内容は次のとおりです。
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
(最初からハッキングについて言及しないでくださいecho
。質問には関係ありません)。
(for host in $(echo $HOSTS); do echo $host; done) | parallel "echo {}; echo '----------------------------------------' ; scp -r $FILES {}: ; echo ''"
問題は、この方法を使用したときの出力が次のscp
ようになることです。
pup
----------------------------------------
soils
----------------------------------------
コマンドが並列に実行されるため、順序が異なり、並列がscpsのforループよりはるかに速く完了するように見えますが、見てのとおり、scpにはstdoutへの出力はありません。理由を理解できません。たとえば、echoからstdoutへの出力は抑制されません。内部で並列化しようとすると、部分的に詳細な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)リモートサーバーではなくリモートサーバーにコピーするように変更してください。