쉘스크립트 병렬실행

참치라이더·2022년 5월 23일
0

선공개분

wait_jobs() {
    local donefiles=("$@")
    for donefile in "${donefiles[@]}"; do until [ -f "${donefile}" ]; do echo -n "." && sleep 1; done && rm -f $donefile; done
}

$servers=("myserver01" "myserver02" "myserver03")

name_jobs=()
for server in "${servers[@]}"; do
    donefile="/tmp/jobname_$server.done"
    name_jobs+=("$donefile")
    ssh $server "COMMAND WHAT YOU WANT" >> /tmp/jobname_$server.result && touch $donefile &
done

wait_jobs "${name_jobs[@]}"

echo "Job done."

무슨 일이 있었나...

하나하나 실행에 시간이 걸리는 작업단위이 있었다. 하나의 작업단위는 여러 서버에 걸쳐 시간이 꽤 걸리는 커맨드를 실행하고 그 결과를 받아와야했다. 각 작업단위는 이전 작업단위가 완전히 끝난 뒤 해당 작업단위의 결과물을 받아와야했다.

이걸 단순히 반복문으로 처리하게 되면 수많은 반복문과 각 반복문 안의 반복문을 말그대로 하나하나 처리해야한다. 그저 컴퓨터가 자동으로 스크립트를 처리해줄 뿐 작업시간 자체는 모든 커맨드를 개별로 실행할때와 다를 것이 없다.

특히나 이런 스크립트를 반복적으로 실행해야하는 경우 작업자가 죽음에 이를 수 있으므로 가뜩이나 구하기 힘든 엔지니어를 지키기 위해서는(나의 경우 나 스스로를 지켰다. 나는 소중하니까.) 커맨드를 병렬로 실행시킬 필요가 있다.

나를 살려줘.

사실 커맨드를 병렬로 실행시키는 것 뿐이라면 각 커맨드나 작은 단위의 스크립트를 백그라운드에서 돌리면 그만이다. 하지만 이 귀여운 작업단위들은 앞단의 작업단위들이 완전히 끝난 다음 작업단위 안의 개별작업들이 각자 STDOUT으로 쏟아낸 결과물을 모두 필요로 했다.

(이런 순간에 가장 필요한 것은 이 작업을 떠넘길 다른 작업자이다. 만약 다른 작업자를 찾을 수 없다면 인력충원을 고려해보자.)

일단 구명조끼를 만들자.(a.k.a. 다른 작업자를 구하지 못함)

우선 함수를 하나 만들자. 쉘스크립트에 정말 함수라는 게 있는지, 아니면 그저 명령묶음에 이름을 붙여주는 건지는 아직도 잘 모르겠지만 일단 만들고보자.

이 함수의 역할은 간단하다. 작업완료파일 리스트를 받아서 반복문에 집어넣고 해당 파일이 완료되었는지 1초마다(혹은 당신이 원하는 작고 소중한 시간마다) 검사하게 한다. 작업완료파일이 생겼으면 해당 파일을 삭제하고 다음 과정으로 넘어간다. 리스트에 적혀있던 모든 작업완료파일들이 생기고나면 최종적으로 해당 함수 컨텍스트를 벗어나게 될 것이다.

나는 한줄짜리 반복문은 정말 한줄로 적어버리는 것을 선호하기 때문에 한줄에 쑤셔넣었지만 좀 더 상냥하게 코드를 짠다면 아래처럼 보일 것이다.

wait_jobs() {
    local donefiles=("$@")
    for donefile in "${donefiles[@]}"; do
        until [ -f "${donefile}" ]; do
            echo -n "." && sleep 1
        done && rm -f $donefile
    done
}

(적고보니 그리 상냥하진 않은 듯...)

더 이상의 설명은 필요없다.

이제 위에서 만든 함수를 바로 사용하면 된다.

작업단위 하나가 반복문 하나라면 해당 반복문 내에서 원하는 커맨드를 백그라운드에서 실행한다. 해당 커맨드의 종료시점에 작업완료파일을 생성하도록 설정하고 해당 작업완료파일의 경로를 작업완료파일 리스트에 걸어주면 된다.

각 반복문의 커맨드는 빠르게 백그라운드로 넘어가고 병렬로 실행될 것이다. 쉘은 곧 작업단위를 넘어서겠지만 wait_job 함수에 의해 모든 작업완료파일이 생성되기까지 기다릴 것이고 작업단위 완료 이후 해당 작업단위에서 떨군 결과파일을 받아오면 된다.

profile
최대한 간략하게 서술하시오.

0개의 댓글