Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

trap를 이용한 signal 처리

signal은 unix 운영체제에서 비동기적인 사건을 전송하기 위해서 사용하는 설비다. 비동기적인 사건이란 언제 발생할지 예측할 수 없는 사건으로 터미널 종료, 메모리 침범, 알람, 장치로 부터의 입력등의 사건이 이에 해당한다. 유닉스 시스템은 이러한 시그널의 처리가 가능하도록 signal(:12)제어용 C 함수들을 제공한다. 그러나 이들 C 인터페이스 함수는 간단한일을 처리하기에는 좀 부담스러운게 사실이다. 여기에 trap(:12)을 이용해서 shell 스크립트로 이벤트를 처리하는 방법을 소개하고자 한다.

시그널은 프로세스에 종속적으로, 해당 프로세스별로 받아들이거나 무시하는 시그널이 정의된다. 그러므로 shell 상에서 이벤트를 처리하는 스크립트를 작성하려면, shell 에서 받아들이는 시그널의 종류에 대해서 알아볼 필요가 있다. 다음은 쉘에서 받아들여서 처리할 수 있는 시그널의 종류들이다.

시그널 번호 시그널 이름 설명
0 EXIT 쉘의 종료
1 HUP 터미널이 종료되었을 때 발생하는 시그널
2 INT Del 키를 눌렀을 때 발생되는 시그널로 현재 프로그램의 중단을 의미한다.
3 QUIT Ctrl + \ 키를 누르면 발생되는 시그널로 현재 프로그램을 종료시킨다.
9 KILL 프로그램을 강제로 종료시키기 위해서 보내는 시그널로 무시하거나 추적해서 처리할 수 없다.
11 SEGV segmentation violation 에 발생되는 시그널이다. 유닉스는 프로세스가 사용하는 메모리 영역을 보호하는데, 다른 프로세스가 사용하는 메모리 영역을 침범하려고 할때 주로 발생한다
15 TERM 이 시그널을 받은 프로세스는 종료가 된다. 기본적인 동작은 KILL 과 같지만 KILL 과는 다르게 무시할 수도 있고, 추적해서 처리할 수도 있다.
시그널에 대한 자세한 내용은 signal문서를 참고하기 바란다.

trap(1)명령어를 이용하면 쉘에서 발생하는 시그널을 처리하는 프로그램을 만들 수 있다. trap(1)의 사용법은 다음과 같다.
trap command signals_list

다음은 INT시그널이 발생할 경우 rm test.txt를 지우는 쉘스크립트다.
# trap "rm test.txt" 2
# echo $$
38500
$$는 쉘의 PID(:12) 값을 저장하고 있는 특수변수다. 이제 다른 쉘을 띄워서 38500 에 INT 시그널을 전송해보자.
# kill -INT 38500
그럼 trap을 실행한 쉘에서 rm test.txt명령이 실행되는걸 확인할 수 있을 것이다.
# rm: remove regular empty file `test.txt'?
y/n 을 물어보는 프롬프트가 뜨지 않고 바로 파일을 삭제시키려면 rm에 -f 옵션을 주면 된다.

다음은 ALRM시그널이 발생할 때 마다 쉘의 HISTORY 변수 이름을 가지는 파일을 특정파일에 저장하는 일을 하는 스크립트다. 로그인한 사용자가 이전에 어떤 작업을 했는지 그 내용을 남기고자 할때 유용하게 사용할 수 있을 것이다.
# trap 'cp $HISTFILE $HOME/old_hist.bak; exit' ALRM