[쉘 스크립트] 쉘 스크립트 기초 - 스크립트 제어 (6)

업데이트:     Updated:

카테고리:

태그:

🎯스크립트 제어

신호 트랩

trap 명령은 리눅스 쉘 스크립트가 어떤 신호를 트랩할 수 있는지를 지정한다. trap 명령의 형식은 다음과 같다.

trap commands signals
  • trap 명령은 signals 필드에 나열된 신호를 수신하면 commands 필드의 명령을 실행한다.
  • signals 필드에는 트랩하고자 하는 신호들을 빈칸으로 구분해서 나열한다. (신호 숫자 값 또는 신호 이름으로 값을 지정할 수 있다.)
$ cat trap.sh p
#!/bin/bash

trap "echo Sprry! I have trapped Ctrl-C" SIGINT

echo "This is a test script"

count=1
while [ $count -le 10 ]
do
    echo "Loop #$count"
    sleep 1
    count=$[ $count + 1 ]
done

echo "This is the end of the test script"
$ ./trap.sh
This is a test script
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
^CSprry! I have trapped Ctrl-C
Loop #6
Loop #7
Loop #8
Loop #9
Loop #10
This is the end of the test script

Note:

두 개의 키보드 조합 <CTRL>+<C>SIGINT 신호를 스크립트에 전달한다.

EXIT 신호 트랩

trap 명령에 EXIT 신호를 트랩하면 쉘 스크립트가 종료될 때 실행될 명령을 지정할 수 있다. 스크립트가 정상 종료 지점에 이르렀거나 강제로 스크립트를 종료할 때 trap 된다.

$ cat trapEXIT.sh 
#!/bin//bash

trap "echo Goodbye..." EXIT

count=1
while [ $count -le 5 ]
do
    echo "Loop #$count"
    sleep 1
    count=$[ $count + 1 ]
done
$ ./trapEXIT.sh 
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
Goodbye...

trap 수정

쉘 스크립트 안에서 trap을 여러 번 지정할 수 있다. 새로운 trap이 동일한 신호를 지정하면 이전의 trap은 덮어쓰여진다.

$ cat trapoverride.sh 
#!/bin/bash

trap "echo Sorry... Ctrl-C is trapped." SIGINT

count=1
while [ $count -le 5 ]
do
    echo "Loop #$count"
    sleep 1
    count=$[ $count + 1 ]
done

trap "echo I modified the trap!" SIGINT

count=1
while [ $count -le 5 ]
do
    echo "Second Loop #$count"
    sleep 1
    count=$[ $count + 1 ]
done
$ ./trapoverride.sh 
Loop #1
Loop #2
Loop #3
Loop #4
^CSorry... Ctrl-C is trapped.
Loop #5
Second Loop #1
Second Loop #2
^CI modified the trap!
Second Loop #3
Second Loop #4
Second Loop #5

trap 제거

일련의 트랩을 제거할 수도 있다. trap 명령 뒤에 두 개의 대시를 사용하고 기본 동작으로 돌아갈 신호의 목록을 지정하면 된다.

$ cat removetrap.sh 
#!/bin/bash

trap "echo Sorry... Ctrl-C is trapped." SIGINT

count=1
while [ $count -le 5 ]
do
    echo "Loop #$count"
    sleep 1
    count=$[ $count + 1 ]
done

trap -- SIGINT
echo "I just removed the trap"

count=1
while [ $count -le 5 ]
do
    echo "Second Loop #$count"
    sleep 1
    count=$[ $count + 1 ]
done
$ ./removetrap.sh 
Loop #1
Loop #2
Loop #3
^CSorry... Ctrl-C is trapped.
Loop #4
Loop #5
I just removed the trap
Second Loop #1
Second Loop #2
^C

Note:

스크립트는 SIGINT 신호를 수신하면 기본적으로 스크립트를 종료하는 방식으로 처리한다.

백그라운드 모드에서 스크립트 실행

백그라운드 프로세스 역시 STDOUT, STDERR 메시지를 리다이렉트 하지 않는 이상 포그라운드 프로세스와 동일하게 출력은 터미널 모니터를 사용한다.

$ cat background.sh 
#!/bin/bash

echo "Start the test script"

count=1
while [ $count -le 5 ]
do
    echo "Loop #$count"
    sleep 5
    count=$[ $count + 1 ]
done

echo "Test script is complete"
$ ./background.sh  &
[1] 2638
$ Start the test script
Loop #1
Loop #2
Loop #3
ls
background.sh  removetrap.sh  trapEXIT.sh  trapoverride.sh  trap.sh
$ Loop #4
Loop #5
Test script is complete

backgound.sh 스크립트를 백그라운드에서 실행하는 동안 ls 명령을 입력했다. 스크립트의 출력, 입력된 명령, 명령의 출력이 모두 출력 표시에 뒤섞였다. 따라서 백그라운드에서 실행시킬 목적으로 만든 스크립트에서는 STDOUT 및 STDERR을 리다이렉트 시키는 것이 좋다.

nohup

  • nohup 명령을 사용하면 프로세스로 전송되는 모든 SIGHUP 신호를 차단한다. 이 명령을 사용하면 터미널 세션을 종료할 때 발생된 SIGHUP 신호가 프로세스와 함께 종료되는 것을 막을 수 있다.
  • nohup 명령은 프로세스와 터미널의 관계를 끊기 때문에 프로세스는 STDOUT 및 STDERR 출력 링크를 잃는다. 명령이 만들어내는 출력을 수용하기 위해 nohup 명령은 STDOUTSTDERR 메시지를 자동으로 nohup.out 이라는 파일로 리다이렉트한다.

📖출처

리처드 블룸, 크리스틴 브레스, ⌜리눅스 커맨드라인 쉘 스크립트 바이블⌟, 스포트라잇북(2016)


👍 개인 공부 기록용 블로그입니다. 오류나 조언이 있으시면 언제든지 댓글 혹은 메일로 남겨주시면 감사하겠습니다! 😄

맨 위로 이동하기

Linux 카테고리 내 다른 글 보러가기

댓글남기기