Ubuntu Linux의 세계에 입문한 이후에 Bash Shell의 강력함에 압도당했고 매료당했다. Windows Shell 보다 문법이 훨씬 더 깔끔하고 직관적이기 때문이다. Bash Script로 무언가를 구현하라고 한다면 큰 어려움 없이 할 수 있겠다. 하지만 Windows Shell로 뭔가를 구현하려고 하면 막막하기 그지없다.
Bash Shell Script가 Windows Batch File보다 훨씬 훌륭하지만, Bash Shell 역시도 처음에 문법을 익히는데 다소 시간이 든다. 구글링과 수많은 시행착오를 거치면 어느 정도 수준까지는 큰 어려움 없이 Bash Shell Script를 작성할 수 있다. (물론 아주 복잡한 연산이나 대량의 데이터를 취급해야 할 경우는 C로 작성하는 게 바람직하다.) 하지만 좀 더 높은 수준의 스크립트를 작성하려면 좀 더 고급 팁이 필요한데, 이것은 구글링으로 습득하기에는 좀 어렵다.
최근에 발견한 상당히 만족스러운 쉘 명령을 기록해두고자 한다. set -e 명령과 set -x 명령이다. 간략하게 설명하자면 set -e 명령은 스크립트에서 수행하는 명령어 또는 함수가 0이 아닌 값을 리턴할 경우 더 이상 스크립트를 수행하지 않는다. set -e 옵션과 함께 사용되는 옵션이 바로 set -x 명령이다. 왜냐하면 set -e 명령에 의해서 스크립트가 도중에 종료되면, 어디에서 종료되었는지 알기 어렵기 때문이다. set -x 명령을 set -e 명령과 함께 주면 이런 경우 스크립트 디버깅을 좀 더 손쉽게 할 수 있다.
set -e
본격적으로 set -e 명령에 대한 사용 방법에 대해서 설명하기에 앞서, 왜 set -e 옵션이 필요한지에 대해서 먼저 설명하도록 하겠다. 많은 엔지니어들이 무엇을 어떻게 구현하거나, 무엇을 어떻게 해결해야 하는지에 대해서는 잘 훈련되어 있는 반면에, 왜 필요하고 왜 해야 하는지에 대해서는 잘 생각하지 않는 경향이 있다. 학교에서 수학 시간에 삼각함수와 미분과 적분을 배우기는 하지만, 왜 배워야 하는지 모른 채로 배우는 경우가 많다. 삼각함수나 미분과 적분에 대해서 배우기 이전에 왜 삼각함수가 필요하고, 왜 미분과 적분이 필요한지에 대해서 먼저 공감하게 되면 더 관심을 가지게 되고 더 잘 배울 수 있을 것이다.
git pull
make clean
make
위의 스크립트는 아주 간단한 스크립트로 git으로부터 소스 코드를 받아와서 clean 작업을 수행한 후에 make 하는 일련의 스크립트이다. 일반적인 상황에서 일상적으로 문제없이 사용하던 스크립트이다. 위의 3가지 명령은 순차적으로 수행되어야 하고, 선행하는 명령이 문제가 발생할 경우 후행하는 명령을 수행할 필요는 없다. 만약 git pull 명령에서 오류가 발생하면 make clean 명령을 수행할 필요가 없고, make clean 명령이 실패하면 make 명령이 수행될 필요가 없다.
git pull && make clean && make
물론 위와 같이 짧게 작성할 수 있겠으나, 순차적으로 수행되는 수십 개의 명령을 위와 같이 사용하기에는 어려움이 따를 것이다.
git pull
if [ $? -ne 0 ]; then
echo "git pull error"
exit -1
fi
make clean
if [ $? - ne 0 ]; then
echo "make clean error"
exit -2
fi
make
if [ $? -ne 0 ]; then
echo "make error"
exit -3
fi
마지막 수행의 성공 여부를 $? 변수를 통해서 확인할 수 있으므로 위와 같이 명령마다 리턴 값을 체크해서 메시지를 출력시키고 종료하는 것도 하나의 방법이다.
하지만 위와 같이 작성하면 각 명령마다 리턴 값을 체크해야 하므로 스크립트도 길어지고 여간 불편한 것이 아니다.
set -e
git pull
make clean
make
드디어 set -e 명령이 등장할 차례이다. set -e 명령을 수행한 이후에 각 명령마다 리턴 값을 체크하고, 0이 아닐 경우 자동으로 종료되게 된다. 즉, git pull 명령에서 실행할 경우 make clean이 수행되지 않은 채로 스크립트가 종료되고, make clean 명령의 수행 결과가 0이 아닐 경우 make 명령이 수행되기에 앞서 종료된다. 세상 편한 명령이 아닐 수 없다.
set +e
set -e 명령도 가능하지만 반대로 set +e 명령도 가능하다.
세상 편한 명령이긴 하지만 분명히 단점도 있다. 어디에서 exit 되었는지 확인하기 어렵다는 것이다. 명령 수행이 실패하면 바로 종료되기 때문에 어느 명령에서 수행 도중에 죽었는지 디버깅하기 어렵다.
set -x
set -x 명령이 등장할 차례이다. set -x 명령의 경우 명령을 실행하기에 앞서서 명령을 출력해주기 때문에 -e 옵션으로 종료되었을 경우 어디서 죽었는지 디버깅하기 용이하다.
$ set -x
$ echo abc
+ echo abc
abc
$
위의 예시는 set -x 명령의 동작을 아주 잘 나타낸다. 'echo abc'라는 명령을 수행하기에 앞서서 어떤 명령이 수행되는지에 대한 정보를 먼저 출력해준다. 에러가 발생할 경우 바로 종료를 시켜주는 set -e 명령과 조합해서 사용하면 디버깅하는데 아주 편리하다.
처음부터 set -e 명령과 set -x 옵션을 동시에 주는 방법도 있고, 처음에는 set -e 명령만 줬다가, retry 시에 set -x 옵션을 추가로 주는 것도 방법이다. 디버그 메시지라는 것은 문제가 발생한 경우에는 요긴하지만, 평시에는 불필요하게 데이터를 낭비하고 읽기도 불편하며 시간도 오래 걸리기 때문이다.
set -e -x
위와 같이 set -e -x 명령을 통해서 -e 옵션과 -x 옵션을 동시에 줄 수 있다.
set -ex
set -ex처럼 두 명령을 동시에 쓸 수도 있다.
set +x
실행 이전에 먼저 출력되는 정보들을 끄고 싶다면 set +x 명령을 사용하면 된다.
끝맺음 말
이상으로 bash 스크립트에서 어떤 명령 또는 함수의 리턴 값이 0이 아닐 경우 자동으로 종료되도록 설정하는 방법과 디버깅 방법에 대한 설명을 마친다. 부디 유용한 정보였기를 바란다.
<더보기>
'Study > Ubuntu 공부' 카테고리의 다른 글
[Ubuntu] 20.04.3에서 한글 입력이 안 되는 경우 조치 방법 (IBus 말고 fcitx로 설정) (0) | 2021.09.14 |
---|---|
[Ubuntu] Linux 업그레이드 이후 키보드와 마우스 잠김 현상 해결 방법 (1) | 2021.08.13 |
[VMware] Ubuntu HDD 파티션 용량 늘리는 방법 (Low Disk Space on Filesystem root) (0) | 2021.02.26 |
[Wine] Wine Mono is not installed 에러 발생시 조치 방법 (0) | 2021.02.15 |
[Ubuntu] 172.20.224.158 IP가 UFW BLOCK 방화벽에 걸렸습니다. (2) | 2021.02.06 |