회사에서 간단한 스크립트를 하나 짜고 싶었는데, 문제가 있었습니다. 일단 예제를 하나 보시죠.

for i in $(seq 5)
do
    echo $i
done

위 for 문을 실행하면 1부터 5까지 숫자가 한번씩 출력될 것인데요, 만약 첫번째 루프에서 echo 1 명령어에 뭔가 문제가 있어서 멈추거나 딜레이가 심해진다면 어떻게 될까요? 하염없이 기다릴 것입니다. 죽이 되든 밥이 되든 명령어의 리턴값이 나와야 다음 루프로 넘어갈 것입니다.

제가 위 예제를 왜 들었냐 하면... 회사에서 Citrix XenServer 기반의 클라우드 시스템을 운영하고 있는데, 아주 가끔 Pool 내의 전체 VM을 강제로 Shutdown 해야 하는 경우가 생깁니다. 1개의 Pool 안에는 16개의 서버가 들어있고, 각 서버에는 몇개의 VM들이 들어있기 때문에, Pool 전체에는 수십개의 VM이 들어있습니다. 그런데 만약 이 Pool 내의 전체 VM을 한번에 Force Shutdown 시키고 싶다면 어떻게 하면 좋을까요?

아래는 제가 작성한 간단한 예제입니다.

xe vm-list is-control-domain=false | grep uuid | awk '{ print $NF }' | while read line
do
    xe vm-shutdown force=true uuid=$line
done

이렇게 하면 Pool 내의 각 VM들의 (Dom0 제외) UUID를 한줄씩 읽어가면서 Force Shutdown 명령어를 뿌려줄 것입니다. 그런데 여기에서 바로 문제에 직면하게 됩니다. 이게 수십번의 루프가 번개같이 샤샤샥 돌아가면 참 좋을텐데, 문제는 각 VM이 완전히 셧다운 되어야 그 다음 루프로 넘어간다는 것입니다. 결국 한 VM당 종료하는데 평균 1분이 소요된다고 가정하면 60개의 VM을 종료하는데 60분이 걸린다는 계산이 나옵니다.

이 문제를 해결하려면 어떻게 해야 할까요?

윈도우에는 start 라는 명령어가 있습니다. 예를 들어 윈도우 배치파일인데 중간에 이런 명령어가 들어있다고 가정하겠습니다. C 드라이브에 있는 readme.txt 파일을 메모장으로 열어서 보여주려고 이렇게 했는데...

notepad c:\readme.txt

이렇게 하면 이 배치파일은 중간에 멈추게 됩니다. 사용자가 저 메모장을 꺼줘야만 다음 줄로 넘어가게 됩니다. 그러니까 저 notepad.exe 프로세스가 종료되어야만 다음 줄로 넘어가게 됩니다.

사용자가 끄지 않더라도 자동으로 다음 줄로 넘어가게 만드려면 어떻게 해야 할까요?

start notepad c:\readme.txt

이렇게 하시면 됩니다. 앞에 start 하나만 붙여주시면 됩니다.

마찬가지로 리눅스에서도 비슷한 효과를 낼 수 있습니다. 바로 백그라운드로 실행하도록 해주는 & 기호입니다. 명령어 뒤에 한칸 띄우고 & 를 붙여주시면 됩니다.

위 XenServer 예제에 & 를 붙이면 이렇게 되겠죠?

xe vm-list is-control-domain=false | grep uuid | awk '{ print $NF }' | while read line
do
    xe vm-shutdown force=true uuid=$line &
done

이렇게 하면 VM이 Shutdown 되든 말든 뒤도 안 돌아보고 다음 루프로 바로바로 넘어가기 때문에 제가 원했던 소기의 목적을 달성할 수 있게 됩니다.