2010-03-02 40 views
3

我想編寫一個Bash腳本,它通過ssh登錄到多臺機器,並首先顯示它們的主機名並執行命令(在每臺機器上執行相同的命令)。主機名和命令的輸出應該一起顯示。我想要一個並行版本,所以ssh命令應該在後臺運行並行運行。Bash:子進程訪問變量

我構建了下面附加的bash腳本。 問題是:由於runonip函數在子shell中執行,因此無法訪問DATA-陣列來存儲結果。是否有可能通過一個「通過引用傳遞」的函數來賦予數組的子shell訪問權限?

代碼:

#!/bin/bash 
set -u 

if [ $# -eq 0 ]; then 
    echo "Need Arguments: Command to run" 
    exit 1 
fi 

DATA="" 
PIDS="" 

#Function to run in Background for each ip 
function runonip { 
    ip="$1" 
    no="$2" 
    cmds="$3" 
    DATA[$no]=$({ 
     echo "Connecting to $ip" 
     ssh $ip cat /etc/hostname 
     ssh $ip $cmds 
    } 2>&1) 
} 

ips=$(get ips somewhere) 

i=0 
for ip in $ips; do 
    #Initialize Variables 
    i=$(($i+1)) 
    DATA[$i]="n/a" 

    #For the RunOnIp Function to background 
    runonip $ip $i [email protected] & 

    #Save PID for later waiting 
    PIDS[$i]="$!" 
done 

#Wait for all SubProcesses 
for job in ${PIDS[@]}; do 
    wait $job 
done 

#Everybody finished, so output the information from DATA 
for x in `seq 1 $i`; do 
    echo ${DATA[$x]} 
done; 

回答

5

不,它真的不是。子shell運行在一個完全獨立的操作系統進程中,兩個進程共享內存的唯一途徑是讓他們的代碼通過系統調用明確地設置它。 Bash不這樣做。

你需要做的是找到兩種進程進行通信的其他方式。的PID命名的臨時文件會是一個方法:

#For the RunOnIp Function to background 
runonip $ip $i [email protected] >data-tmp& 
mv data-tmp data-$! 

然後貓的文件:

#Everybody finished, so output the information from the temp files 
for x in ${PIDS[@]}; do 
    cat data-$x 
    rm data-$x 
done;