여러 SSH 명령을 병렬로 실행하고 출력을 변수에 저장하는 방법

여러 SSH 명령을 병렬로 실행하고 출력을 변수에 저장하는 방법

ssh여러 호스트에 로그인하고 , 일부 명령을 실행하고, 실행 요약을 인쇄하는 쉘 스크립트를 작성하려고 합니다 . 지금까지 나는 다음에서 작동하는 것을 작성했습니다.순서대로방법. 하지만 속도가 느리기 때문에 병렬 방식으로 다시 작성하고 싶습니다. 나는 이것을 사용하여 &여러 ssh 명령을 병렬로 실행하고 "명령 대체"를 사용하여 subshell출력을 변수에 저장할 수 있다는 것을 알고 있습니다. 하지만 올바르게 결합할 수는 없습니다.

지금까지 이러한 코드를 출력했습니다. 그러나 여전히 순차적으로 실행됩니다.

#!/bin/bash

hosts=( 'host-1' 'host-2' 'host-3' )

cmd='sleep $[ (( $RANDOM % 20 ) + 1) /10 ]s && echo hello world'
i=0
for host in ${hosts[@]}; do
    var1=$(ssh $host $cmd &)
    echo "i = $i"
    outputs[i]="$var1"
    ((i++))
done

echo 'wait'
wait

echo ${outputs[@]}

답변1

백그라운드 작업이 하위 쉘에서 실행되기 때문에 명령 대체 여부에 관계없이 백그라운드에서 변수 할당을 효과적으로 사용할 수 없다고 생각합니다. 예를 들어

foo=x
foo=$(echo y) &
echo "$foo"

x서브쉘에 대해서만 두 번째 할당을 인쇄합니다 .

반면에 명령 대체 내에서 백그라운드로 실행하면 원하는 작업이 수행되지 않으며 쉘은 어쨌든 명령을 기다리며 작업을 순차적으로 실행하게 됩니다.

sleepecho() { sleep "$1"; echo "$2"; }
foo=$( sleepecho 5 abc & )      # returns after five seconds
echo "$foo"                     # prints 'abc'

당신이 할 수 있는 일은 명령의 출력을 임시 파일에 저장하는 것입니다. 이렇게 하면 배경이 작동하게 되며 출력이 길면 더 좋을 수도 있습니다.

dir=$(mktemp -d)
for h in "${hosts[@]}" ; do
    ssh "$h" "$cmd" > "$dir/$h" & 
done
wait
do something with "$dir/"*

ssh여러 호스트에서 명령을 실행하기 위한 기성 솔루션이 많이 있지만 ...

관련 정보