2010-03-02 6 views
3

ssh를 통해 여러 머신에 loggs하고 호스트 이름을 표시하고 명령을 실행하는 Bash 스크립트를 작성하려고합니다 (모든 머신에서 동일한 명령). 명령의 호스트 이름과 출력이 함께 표시되어야합니다. 병렬 버전을 원했기 때문에 ssh 명령은 백그라운드에서 병렬로 실행해야합니다.Bash : 서브 프로세스 액세스 변수

아래와 같이 bashscripted를 구성했습니다. 문제는 다음과 같습니다. runonip -function이 하위 셸에서 실행되므로 결과를 저장하기 위해 DATA 배열에 액세스 할 수 없습니다. 함수에 대한 "참조에 의한 전달"을 통해 아마도 서브 셸에 Array에 대한 액세스를 제공 할 수 있습니까?

코드 :

#!/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

아니, 정말 아니에요. 서브 쉘은 완전히 별개의 운영 체제 프로세스에서 실행되며 두 프로세스가 메모리를 공유하는 유일한 방법은 코드가 시스템 호출을 통해이를 명시 적으로 설정하는 것입니다. 배쉬는 그렇게하지 않습니다.

두 프로세스가 통신 할 수있는 다른 방법을 찾아야합니다.

#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; 
3

당신은 간 통신을 할 수있는 named pipe을 설정할 수 있습니다 PID를 이름을 따서 명명 임시 파일은 하나 개의 방법이 될 것입니다.

또 다른 가능성은 Bash 4에서 coprocesses을 사용하는 것일 수 있습니다.

추가 참조 :

+0

Coprocesses 명확하게 바로이 문제와 다른 사람에 의해 발명되었다 - 멋진! –