리눅스는 시스템에서 실행되는 프로세스와 통신하기 위해 신호
를 사용합니다.
프로세스를 중지, 시작, 종료하기 위해 이러한 신호를 사용합니다.
신호 | 값 | 설명 |
---|---|---|
1 | SIGHUP | 프로세스를 끊음 |
2 | SIGINT | 프로세스 중지 |
3 | SIGQUIT | 프로세스 중단 |
9 | SIGKILL | 무조건 프로세스 종료 |
15 | SIGTERM | 가능하면 프로세스를 종료 |
17 | SIGSTOP | 무조건 프로세스를 중단(종료 X) |
18 | SIGTSTP | 프로세스 중단 또는 일시 중지(종료 X) |
19 | SIGCONT | 중단된 프로세스를 실행 |
[Ctrl] + [C]
SIGINT
신호(프로세스 중지
)를 만들어냅니다.
$ sleep 100
^C
$
[Ctrl] + [Z]
SIGTSTP
신호(프로세스를 중단 또는 일시중지(종료 x)
)를 만들어냅니다.
프로세스를 중지시키는 것은 종료
와는 다릅니다. 프로세스를 중지하면 프로그램을 메모리에 남겨두며 중단되었던 곳에서부터 동작을 재개시킬 수 있습니다.
$ sleep 100
^Z
[1]+ Stopped sleep 100
만약 종료시키려 한다면 중단된 프로세스가 존재한다는 메시지
를 출력합니다.
$ exit
logout
There are stopped jobs.
ps
명령으로 중단된 작업을 볼 수 있습니다.
$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 583315 583279 0 80 0 - 2102 do_wai pts/0 00:00:00 bash
0 T 1000 583456 583315 0 80 0 - 1369 do_sig pts/0 00:00:00 sleep
0 R 1000 583485 583315 0 80 0 - 2202 - pts/0 00:00:00 ps
$ kill -9 <PID>
SIGKILL
신호(무조건 프로세스 종료
)를 생성합니다.
$ kill -9 583456
$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 583315 583279 0 80 0 - 2102 do_wai pts/0 00:00:00 bash
0 R 1000 583553 583315 0 80 0 - 2202 - pts/0 00:00:00 ps
[1]+ Killed sleep 100
만약 스크립트가 실행되고 있는 와중에 특정 신호가 발생한다면, 이를 가로챌(트랩
) 수 있습니다.
trap commands signals
예를 들어, trap "echo ' You can't stop this script!'" SIGINT
를 명령하면 SIGINT
신호가 들어올 때 가로채서(트랩
) 정의된 명령어를 실행하고, 스크립트에 영향이 없도록 합니다.
아래 스크립트는 SIGINT
신호가 들어왔을 때 트랩해서 스크립트 실행이 중단되지 않도록 합니다.
$ cat test1
#!/bin/bash
trap "echo ' You cannot stop this script'" SIGINT
count=1
while [ $count -le 10 ]
do
echo "Line #$count"
sleep 1
count=$[ $count + 1 ]
done
$ ./test1
Line #1
Line #2
Line #3
Line #4
Line #5
^C You cannot stop this script
Line #6
Line #7
^C You cannot stop this script
Line #8
Line #9
Line #10
[Ctrl] + [C]
를 눌러 SIGINT
신호를 발생시켰지만 trap
이 가로채서 스크립트 실행에는 영향이 없는 모습을 볼 수 있습니다.
trap
을 사용할 때 EXIT
를 입력하면 스크립트가 종료될 때 트랩할 수 있습니다.
$ cat test1
#!/bin/bash
trap "echo 'script exit...'" EXIT
count=1
while [ $count -le 5 ]
do
echo "Line #$count"
sleep 1
count=$[ $count + 1 ]
done
$ ./test1
Line #1
Line #2
Line #3
Line #4
Line #5
script exit...
같은 신호에 대한 트랩에 대해서 수정
할 수 있습니다.
수정하는 법은 간단합니다.
단순히 trap
을 한 번 더 작성하면 됩니다.
$ cat test1
#!/bin/bash
trap "echo 'You cannot stop first loop!'" SIGINT
count=1
while [ $count -le 5 ]
do
echo "Line #$count"
sleep 1
count=$[ $count + 1 ]
done
trap "echo 'You cannot stop second loop!!'" SIGINT
count=1
while [ $count -le 5 ]
do
echo "2 - Line #$count"
sleep 1
count=$[ $count + 1 ]
done
$ ./test1
Line #1
Line #2
^CYou cannot stop first loop!
Line #3
Line #4
Line #5
2 - Line #1
2 - Line #2
2 - Line #3
^CYou cannot stop second loop!!
2 - Line #4
2 - Line #5
기존의 트랩을 제거할 수도 있습니다.
trap -- <signal>
의 형식으로 제거가 가능합니다.
$ cat test1
#!/bin/bash
trap "echo 'You cannot stop first loop!'" SIGINT
count=1
while [ $count -le 5 ]
do
echo "Line #$count"
sleep 1
count=$[ $count + 1 ]
done
trap -- SIGINT
count=1
while [ $count -le 5 ]
do
echo "2 - Line #$count"
sleep 1
count=$[ $count + 1 ]
done
$ ./test1
Line #1
Line #2
^CYou cannot stop first loop!
Line #3
Line #4
Line #5
2 - Line #1
2 - Line #2
^C
두 번째 루프에서는 SIGINT
신호가 제대로 동작하는 것을 확인할 수 있습니다.