내밥줄/프로그래밍

bash에서 블록 빠져나가기 트릭

jjoell 2013. 5. 29. 11:30

bash로 스크립트를 짜다가 특정 명령이 실패하면 나머지 부분을 스킵해야할 일이 생겼다.

bash에는 goto가 없다. 따라서 특정 위치로 점프하기 위해서는 case나 while 등을 써서 이를 흉내내줘야 한다.

while로 조잡하게 구현했다.


while true

do

    command

    if [ $? -ne 0 ];then

        break

    fi

    # command가 실패인 경우 나머지는 실행하지 않음

    ...

    break

done


잘 동작한다. 심지어 함수 내에서 break를 써도 된다.


하지만 보기에 심히 좋지 못해 alias를 사용해 덮어버린다.


alias block_begin="while true;do"

alias block_break="break 99"

alias block_end="break;done"


block_begin

    command

    if [ $? -ne 0 ];then

        block_break

    fi

    # command가 실패인 경우 나머지는 실행하지 않음

    ...

block_end


...잘 동작할 줄 알았는데 안 된다.

alias는 interactive 모드 즉 쉘 상에서 직접 실행하는 것이 아니면 동작하지 않기 때문이다.


이 문제는

shopt -s expand_aliases

를 추가하면 해결된다. 대신 엉뚱한 명령이 alias 되지 않도록 주의해야한다.

이 명령과 alias 부분을 따로 파일로 만들어서 source나 .으로 먼저 실행되게 하니 편리했다.

break 99 를 한 이유는 블록 내의 loop 내에서 사용할 경우 해당 loop 뿐만 아니라 block_end 밖까지 빠져나오기 위함이다.


대부분 이정도 선에서 거의 해결되겠지만 내 경우 또 다른 문제가 생겼다.

그냥 function을 실행하여 내부에서 break를 사용하는 경우 블럭을 잘 빠져나오지만 

$(), `` 또는 |를 사용하는 경우처럼 자식 프로세스를 생성하여 실행하는 경우 무용지물이 된다.


고민하다 병신같지만 signal을 사용하여 해결했다.

block을 빠져나가야 할 경우 /proc에서 최초 부모 프로세스를 찾아 USR1을 날리고

이를 잡아 break를 하는 function을 만들어 block_break대신 사용하였다.

'내밥줄 > 프로그래밍' 카테고리의 다른 글

vim 설정  (0) 2017.04.17
vim indentation  (0) 2015.01.16
[펌] [linux] AWK & SED chunk 2  (0) 2013.05.16
[펌]Can I do "make uninstall" with CMake?  (0) 2013.04.16
[bash] unset 변수와 empty 값 변수 구별  (0) 2013.01.25