天天看點

Shell程式設計之Linux信号及信号跟蹤

本文介紹Shell程式設計之Linux信号及信号跟蹤

一、Linux信号

1.什麼是信号?

Linux信号是由一個整數構成的異步消息,它可以由某個程序發給其他程序,也可以在使用者按下特定鍵發生某種異常事件時,由系統發給某個程序。

2.信号清單

Shell程式設計之Linux信号及信号跟蹤
[root@codis-178 ~]# trap -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	
           

3.使用trap控制信号

用途:

  • 在腳本程式被中斷時完成清理工作
  • 屏蔽使用者非法使用的某些信号

trap指令:

trap command signal

說明:

  • command 接收到指定信号時将要采取的行動
  • signal 要處理的信号名

(1)測試trap指令捕獲ctrl + c信号

[root@codis-178 ~]# trap 'echo oldboy' 2
[root@codis-178 ~]# ^Coldboy

[root@codis-178 ~]# ^Coldboy

[root@codis-178 ~]# trap 'echo oldgirl' INT
[root@codis-178 ~]# ^Coldgirl
           

stty可以列出中斷信号與鍵盤的對應資訊

[root@codis-178 ~]# stty -a
speed 38400 baud; rows 34; columns 192; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O;
min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -cdtrdsr
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
           

(2)測試按下ctrl + c組合鍵而引發的INT(2)信号

[root@codis-178 ~]# trap "" 2
[root@codis-178 ~]# trap ":" 2
[root@codis-178 ~]# ^C
[root@codis-178 ~]# trap "echo -n 'you are typing ctrl+c'" 2
[root@codis-178 ~]# ^Cyou are typing ctrl+c
[root@codis-178 ~]# ^Cyou are typing ctrl+c
           

(3)同時處理多個信号

[root@codis-178 ~]# trap "" 1 2 3 20 15
[root@codis-178 ~]# trap ":" 1 2 3 20 15
[root@codis-178 ~]# ^C
[root@codis-178 ~]# trap "" `echo (1..64)`  #屏蔽1-64的所有信号
           

4.企業應用

(1)實作觸發信号後清理檔案的功能

[root@codis-178 ~]# cat 17_1.sh 
#!/bin/bash
#Author:xiaoda
#Time:2017-09-06 10:47:59
#Name:17_1.sh
#Version:V1.0
#Description:This is a test script

trap "find /tmp -type f -name "oldboy_*"|xargs rm -f && exit" INT
while true
do
	touch /tmp/oldboy_$(date +%F-%H-%M-%S)
	sleep 3
	ls -l /tmp/oldboy*
done
[root@codis-178 ~]# sh 17_1.sh 
-rw-r--r-- 1 root root 0 Sep  6 10:50 /tmp/oldboy_2017-09-06-10-50-54
-rw-r--r-- 1 root root 0 Sep  6 10:50 /tmp/oldboy_2017-09-06-10-50-54
-rw-r--r-- 1 root root 0 Sep  6 10:50 /tmp/oldboy_2017-09-06-10-50-57
-rw-r--r-- 1 root root 0 Sep  6 10:50 /tmp/oldboy_2017-09-06-10-50-54
-rw-r--r-- 1 root root 0 Sep  6 10:50 /tmp/oldboy_2017-09-06-10-50-57
-rw-r--r-- 1 root root 0 Sep  6 10:51 /tmp/oldboy_2017-09-06-10-51-00
^C[root@codis-178 ~]# ls -l /tmp
total 4
drwxr-xr-x 2 root  root  4096 Sep  5 18:40 hsperfdata_root
srwxrwxrwx 1 mysql mysql    0 Feb  9  2017 mysql.sock
           

(2)企業級Shell跳闆機

要求使用者登入到跳闆機後隻能執行管理者給定的選項動作,不允許以任何形式中斷腳本而到跳闆機伺服器上執行系統指令。

echo '[ $UID -ne 0 ] && . /server/scripts/jump.sh' >/etc/profile.d/jump.sh

[root@codis-178 ~]# cat jump.sh 
#!/bin/bash
#Author:xiaoda
#Time:2017-09-06 10:56:56
#Name:jump.sh
#Version:V1.0
#Description:This is a test script

trapper(){
	trap ":" INT EXIT TSTP TERM HUP
}

main(){
	while :
	do
		trapper
		clear
		cat <<menu
			1)WEB01-192.168.1.1
			2)WEB01-192.168.1.2
			3)DB01-172.16.1.1
		menu
			read -p "Pls input a num:" num
			case "$num" in
				1)
					echo 'login in 192.168.1.1'
				2)
					echo 'login in 192.168.1.2'
				3)
					echo 'login in 172.16.1.1'
				*)
					echo 'select error.'
		esac
	done
}
main