2012-12-03 24 views
3

有很多關於並行SSH的線程和文檔,但我找不到任何關於傳遞自定義參數到每個主機。使用pssh爲例,hosts文件被定義爲:並行SSH與自定義參數到每個主機

111.111.111.111 
222.222.222.222 

不過,我想通過一個shell腳本傳遞自定義的參數到每個主機,像這樣:

111.111.111.111 param1a param1b ... 
222.222.222.222 param2a param2b ... 

或者,更好,主機和參數將在2個文件之間分割。

因爲這不常見,這是濫用並行ssh嗎?我應該從腳本創建很多ssh進程嗎?我應該如何處理這個問題?

+0

我目前的解決方案是創建ssh進程並將它們作爲背景並等待它們完成。這在我的情況下效果很好,因爲我可以傳遞我想要的參數,但它使我必須管理日誌並自行控制它們。 –

回答

4

你可以使用GNU parallel

假設你有一個文件argfile

111.111.111.111 param1a param1b ... 
222.222.222.222 param2a param2b ... 

然後運行

parallel --colsep ' ' ssh {1} prog {2} {3} ... :::: argfile 

將與相應的參數每個主機上運行prog。每個主機的參數數量必須相同。

+0

太棒了!自從我看過這些東西以來,這已經有一段時間了,但如果這樣做,它看起來就是最優雅的解決方案。我在原來的問題中沒有提到我有任意數量的服務器將這些參數傳遞給(可能是幾百個),並且這似乎很容易擴展。感謝分享! –

+1

如果你的參數包含空格,那麼你可能希望使用TAB(\ t)作爲--colsep(如果argfile來自電子表格,特別方便)。 –

+2

如果您仍想將主機和參數分成2個文件,則使用--xapply,它將從每個輸入源讀取一行:parallel --xapply ssh {1} prog {2} :::: hosts argfile –

0

這裏是您可以使用,剪裁之後,以滿足您的需求的解決方案:

#!/bin/bash 
#filename: example.sh 
#usage: ./example.sh <par1> <par2> <par3> ... <par6> 

#set your ip addresses 
$traf1=1.1.1.1 
$traf2=2.2.2.2 
$traf3=3.3.3.3 

#set some custom parameters for your scripts and use them as you wish. 
#In this example, I use the first 6 command line parameters passed when run the example.sh 


ssh -T $traf1 -l username "/export/home/path/to/script.sh $1 $2" 1>traf1.txt 2>/dev/null & 
echo "Fetching data from traffic server 2..." 
ssh -T $traf2 -l username "/export/home/path/to/script.sh $3 $4" 1> traf2.txt 2>/dev/null & 
echo "Fetching data from traffic server 3..." 
ssh -T $traf3 -l username "/export/home/path/to/script.sh $5 $6" 1> traf3.txt 2>/dev/null & 

#your application will block on this line, and will only continue if all 
#3 remotely executed scripts will complete 
wait 

請記住,上面要求你設置passwordless login機器之間,否則該解決方案將突破要求用於密碼輸入。

0

如果你可以使用Perl:

use Net::OpenSSH::Parallel; 
use Data::Dumper; 

my $pssh = Net::OpenSSH::Parallel->new; 

$pssh->add_host('111.111.111.111'); 
$pssh->add_host('222.222.222.222'); 

$pssh->push('111.111.111.111', $cmd, $param11, $param12); 
$pssh->push('222.222.222.222', $cmd, $param21, $param22); 

$pssh->run; 

if (my %errors = $ssh->get_errors) { 
    print STDERR "ssh errors:\n", Dumper \%errors; 
}