linux下的trap命令
生活随笔
收集整理的這篇文章主要介紹了
linux下的trap命令
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?trap命令用于指定在接收到信號后將要采取的動作。常見的用途是在腳本程序被中斷時完成清理工作。不過,這次我遇到它,是因為客戶有個需求:從終端訪問服務器的用戶,其登陸服務器后會自動運行某個命令,例如打開應用(命令寫在.bashrc等文件中),最后退出,并斷開連接;期間是不能允許其使用Ctrl+C等中斷退出應用,而回到Shell環境,否則可能會帶來安全問題。
????當然,解決的方式有很多,如在應用中屏蔽中斷信號、使用chroot方式訪問等。但這些方法都有一些限制,如需要修改應用,讓telnet等支持chroot方式(ssh可支持chroot)等。而使用trap也是一種比較好的解決方法。
一、關于信號
歷史上,shell總是用數字來代表信號,而新的腳本程序應該使用信號的名字,它們保存在用#include命令包含進來的signal.h頭文件中,在使用信號名時需要省略SIG前綴。
kill和trap等都可以看到信號編號及其關聯的名稱。“信號”是指那些被異步發送到一個程序的事件。默認情況下,它們通常會終止一個程序的運行。
引用 # 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???? 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
附錄中有個說明文檔。
二、trap 的使用
1、運行格式
trap命令的參數分為兩部分,前一部分是接收到指定信號時將要采取的行動,后一部分是要處理的信號名。
trap command signal
它有三種形式分別對應三種不同的信號回應方式。
第一種:
trap "commands" signal-list
當腳本收到signal-list清單內列出的信號時,trap命令執行雙引號中的命令。
第二種:
trap signal-list
trap不指定任何命令,接受信號的默認操作,默認操作是結束進程的運行。
第三種:
trap " " signal-list
trap命令指定一個空命令串,允許忽視信號,我們用到的就是這一種。
※ 請記住,腳本程序通常是以從上到下的順序解釋執行的,所以必須在你想保護的那部分代碼以前指定trap命令。
2、測試
按照用戶的要求,我們需要屏蔽的是HUP INT QUIT TSTP幾個信號。所以,可以運行:
# trap "" HUP INT QUIT TSTP
這個時候,可以試試打開一個持續的命令,然后中斷其運行,例如:
# tail -f /var/log/messages
接著,試試用Ctrl+C 或 Ctrl+\ 來中斷試試,會程序是不會退出的。
3、恢復信號
如果想恢復的話,可以用Ctrl+Z把程序放到后臺,然后運行:
# trap : HUP INT QUIT TSTP
然后,用ps -ef看看其PID號,bg 1讓程序繼續運行,最后用kill 殺掉即可。
4、其他
您也可以試試運行:
# trap "echo 'Hello World' " HUP INT QUIT TSTP
這樣,當您運行Ctrl+C 等中斷時,會自動運行echo命令,結果就是現實Hello World字符串:
引用 # tail -f /var/log/messages
May 18 16:57:54 192.168.228.153 dhcpd: DHCPREQUEST for 192.168.228.221 from 00:1d:72:92:d4:68 via eth0
May 18 16:57:54 192.168.228.153 dhcpd: DHCPACK on 192.168.228.221 to 00:1d:72:92:d4:68 via eth0
[root@mail ~]# Hello World
※ 注意,這方式并不能屏蔽中斷,敲入Ctrl+C 等信息后,仍以默認行為動作的,也就是退出程序,僅會再運行一個額外的命令而已。
三、附錄
1、中斷按鍵
不同的終端類型、Shell版本其中斷的按鍵是不同的,甚至還可以自定義,這可通過stty命令查詢:
引用 # stty -a
speed 38400 baud; rows 30; columns 111; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol =?; eol2 =?; 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
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel
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
^就是Ctrl的縮寫。
2、信號詳情
引用 名稱??????默認動作????????????說明
SIGHUP??????終止進程??????終端線路掛斷
SIGINT????終止進程??????中斷進程
SIGQUIT?? 建立CORE文件??終止進程,并且生成core文件
SIGILL????建立CORE文件????????非法指令
SIGTRAP?? 建立CORE文件????????跟蹤自陷
SIGBUS????建立CORE文件????????總線錯誤
SIGSEGV?? 建立CORE文件????????段非法錯誤
SIGFPE????建立CORE文件????????浮點異常
SIGIOT????建立CORE文件????????執行I/O自陷
SIGKILL?? 終止進程??????殺死進程
SIGPIPE?? 終止進程??????向一個沒有讀進程的管道寫數據
SIGALARM??終止進程??????計時器到時
SIGTERM?? 終止進程??????軟件終止信號
SIGSTOP?? 停止進程??????非終端來的停止信號
SIGTSTP?? 停止進程??????終端來的停止信號
SIGCONT?? 忽略信號??????繼續執行一個停止的進程
SIGURG????忽略信號??????I/O緊急信號
SIGIO???? 忽略信號??????描述符上可以進行I/O
SIGCHLD?? 忽略信號??????當子進程停止或退出時通知父進程
SIGTTOU?? 停止進程??????后臺進程寫終端
SIGTTIN?? 停止進程??????后臺進程讀終端
SIGXGPU?? 終止進程??????CPU時限超時
SIGXFSZ?? 終止進程??????文件長度過長
SIGWINCH??忽略信號??????窗口大小發生變化
SIGPROF?? 終止進程??????統計分布圖用計時器到時
SIGUSR1?? 終止進程??????用戶定義信號1
SIGUSR2?? 終止進程??????用戶定義信號2
SIGVTALRM 終止進程??????虛擬計時器到時
更多的示例,可見:? 這里 。
????當然,解決的方式有很多,如在應用中屏蔽中斷信號、使用chroot方式訪問等。但這些方法都有一些限制,如需要修改應用,讓telnet等支持chroot方式(ssh可支持chroot)等。而使用trap也是一種比較好的解決方法。
一、關于信號
歷史上,shell總是用數字來代表信號,而新的腳本程序應該使用信號的名字,它們保存在用#include命令包含進來的signal.h頭文件中,在使用信號名時需要省略SIG前綴。
kill和trap等都可以看到信號編號及其關聯的名稱。“信號”是指那些被異步發送到一個程序的事件。默認情況下,它們通常會終止一個程序的運行。
引用 # 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???? 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
附錄中有個說明文檔。
二、trap 的使用
1、運行格式
trap命令的參數分為兩部分,前一部分是接收到指定信號時將要采取的行動,后一部分是要處理的信號名。
trap command signal
它有三種形式分別對應三種不同的信號回應方式。
第一種:
trap "commands" signal-list
當腳本收到signal-list清單內列出的信號時,trap命令執行雙引號中的命令。
第二種:
trap signal-list
trap不指定任何命令,接受信號的默認操作,默認操作是結束進程的運行。
第三種:
trap " " signal-list
trap命令指定一個空命令串,允許忽視信號,我們用到的就是這一種。
※ 請記住,腳本程序通常是以從上到下的順序解釋執行的,所以必須在你想保護的那部分代碼以前指定trap命令。
2、測試
按照用戶的要求,我們需要屏蔽的是HUP INT QUIT TSTP幾個信號。所以,可以運行:
# trap "" HUP INT QUIT TSTP
這個時候,可以試試打開一個持續的命令,然后中斷其運行,例如:
# tail -f /var/log/messages
接著,試試用Ctrl+C 或 Ctrl+\ 來中斷試試,會程序是不會退出的。
3、恢復信號
如果想恢復的話,可以用Ctrl+Z把程序放到后臺,然后運行:
# trap : HUP INT QUIT TSTP
然后,用ps -ef看看其PID號,bg 1讓程序繼續運行,最后用kill 殺掉即可。
4、其他
您也可以試試運行:
# trap "echo 'Hello World' " HUP INT QUIT TSTP
這樣,當您運行Ctrl+C 等中斷時,會自動運行echo命令,結果就是現實Hello World字符串:
引用 # tail -f /var/log/messages
May 18 16:57:54 192.168.228.153 dhcpd: DHCPREQUEST for 192.168.228.221 from 00:1d:72:92:d4:68 via eth0
May 18 16:57:54 192.168.228.153 dhcpd: DHCPACK on 192.168.228.221 to 00:1d:72:92:d4:68 via eth0
[root@mail ~]# Hello World
※ 注意,這方式并不能屏蔽中斷,敲入Ctrl+C 等信息后,仍以默認行為動作的,也就是退出程序,僅會再運行一個額外的命令而已。
三、附錄
1、中斷按鍵
不同的終端類型、Shell版本其中斷的按鍵是不同的,甚至還可以自定義,這可通過stty命令查詢:
引用 # stty -a
speed 38400 baud; rows 30; columns 111; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol =?; eol2 =?; 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
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel
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
^就是Ctrl的縮寫。
2、信號詳情
引用 名稱??????默認動作????????????說明
SIGHUP??????終止進程??????終端線路掛斷
SIGINT????終止進程??????中斷進程
SIGQUIT?? 建立CORE文件??終止進程,并且生成core文件
SIGILL????建立CORE文件????????非法指令
SIGTRAP?? 建立CORE文件????????跟蹤自陷
SIGBUS????建立CORE文件????????總線錯誤
SIGSEGV?? 建立CORE文件????????段非法錯誤
SIGFPE????建立CORE文件????????浮點異常
SIGIOT????建立CORE文件????????執行I/O自陷
SIGKILL?? 終止進程??????殺死進程
SIGPIPE?? 終止進程??????向一個沒有讀進程的管道寫數據
SIGALARM??終止進程??????計時器到時
SIGTERM?? 終止進程??????軟件終止信號
SIGSTOP?? 停止進程??????非終端來的停止信號
SIGTSTP?? 停止進程??????終端來的停止信號
SIGCONT?? 忽略信號??????繼續執行一個停止的進程
SIGURG????忽略信號??????I/O緊急信號
SIGIO???? 忽略信號??????描述符上可以進行I/O
SIGCHLD?? 忽略信號??????當子進程停止或退出時通知父進程
SIGTTOU?? 停止進程??????后臺進程寫終端
SIGTTIN?? 停止進程??????后臺進程讀終端
SIGXGPU?? 終止進程??????CPU時限超時
SIGXFSZ?? 終止進程??????文件長度過長
SIGWINCH??忽略信號??????窗口大小發生變化
SIGPROF?? 終止進程??????統計分布圖用計時器到時
SIGUSR1?? 終止進程??????用戶定義信號1
SIGUSR2?? 終止進程??????用戶定義信號2
SIGVTALRM 終止進程??????虛擬計時器到時
更多的示例,可見:? 這里 。
總結
以上是生活随笔為你收集整理的linux下的trap命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rpm命令选项中文说明
- 下一篇: History命令用法