活學(xué)活用掌握trap命令

trap
?命令用于指定在接收到信號(hào)后將要采取的動(dòng)作,常見(jiàn)的用途是在腳本程序被中斷時(shí)完成清理工作。當(dāng)?shell
?接收到?sigspec
?指定的信號(hào)時(shí),?arg
?參數(shù)(通常是執(zhí)行命令)會(huì)被讀取,并被執(zhí)行。

? 1. 命令介紹??
開(kāi)始掌握基本的使用方式和方法
[1] 語(yǔ)法格式
trap [-lp] [[arg] sigspec ...]
[2] 參數(shù)選項(xiàng)
編號(hào)參數(shù)含義1-p
列出當(dāng)前設(shè)置的 trap 方法2-l
列出信號(hào)名稱和相應(yīng)的數(shù)字
[3] 常用的信號(hào)量
NumberNameNotes0EXIT
Always run on shell exit, regardless of exit code1SIGHUP
-2SIGINT
This is what?^C
?sends3SIGQUIT
-6SIGABRT
-9SIGKILL
-14SIGALRM
-15SIGTERM
This is what?kill
?sends by default
? 2. 實(shí)例說(shuō)明??
紙上得來(lái)終覺(jué)淺,絕知此事要躬行。
[1] 累計(jì)在退出時(shí)運(yùn)行的
trap
工作列表
# on_exit and add_on_exit
# Usage:
# ? add_on_exit rm -f /tmp/foo
# ? add_on_exit echo "I am exiting"
# ? tempfile=$(mktemp)
# ? add_on_exit rm -f "$tempfile"
function on_exit() {
? ?for i in "${on_exit_items[@]}"; do
? ? ? ?eval $i
? ?done
}
function add_on_exit() {
? ?local n=${#on_exit_items[*]}
? ?on_exit_items[$n]="$*"
? ?if [[ $n -eq 0 ]]; then
? ? ? ?trap on_exit EXIT
? ?fi
}
add_on_exit echo "I am exiting"
[2] 捕獲
SIGINT
或Ctrl+C
# Run a command on signal 2 (SIGINT, which is what ^C sends)
function sigint() {
? ?echo "Killed subshell!"
}
trap sigint INT
# This will be killed on the first ^C
echo "Sleeping..."
sleep 500
echo "Sleeping..."
sleep 500
# ?pressing ^C twice in a second to quit
last=0
function allow_quit() {
? ?[ $(date +%s) -lt $(( $last + 1 )) ] && exit
? ?echo "Press ^C twice in a row to quit"
? ?last=$(date +%s)
}
trap allow_quit INT
[3] 清理臨時(shí)文件
# Make a cleanup function
function cleanup() {
?rm --force -- "${tmp}"
}
# Trap special "EXIT" group, which is always run when the shell exits.
trap cleanup EXIT
# Create a temporary file
tmp="$(mktemp -p /tmp tmpfileXXXXXXX)"
echo "Hello, world!" >> "${tmp}"
[4] 在退出時(shí)殺死子進(jìn)程
# kill all spawned child processes of the shell on exit
trap 'jobs -p | xargs kill' EXIT
[5] 對(duì)終端窗口大小的變化做出反應(yīng)
# signal WINCH(WINdowCHange) that is fired when one resizes a terminal window
declare -x rows cols
function update_size(){
?rows=$(tput lines) # get actual lines of term
?cols=$(tput cols) ?# get actual columns of term
?echo DEBUG terminal window has no $rows lines and is $cols characters wide
}
trap update_size WINCH
? 3. 刪除進(jìn)程樹(shù)??
一條命令也可以完成一個(gè)腳本的工作量
# How to get PID,PGID,sessionid etc ?
$ ps -o pid,ppid,pgid,gid,sess,cmd -U root
?PID ?PPID ?PGID ? GID ?SESS CMD
# 1.kill a group of processes with negative PID(Process ID)
新的一年新的征程新的課程開(kāi)班等你來(lái)學(xué)!
$ kill ?-TERM -PID
# 2. kill a group of processes with their PGID(Process Group ID)
$ kill -- -$PGID ? Kill using the default signal (TERM = 15)
$ kill -9 -$PGID ? Kill using the KILL signal (9)
# 3. kill a group processes with only PID info
$ kill -- -$(ps -o pgid= $PID | grep -o [0-9]*)
# 4.Using pkill, kill processes by PGID(Proess Group ID)
$ pkill -9 -g $PGID
# 5.Using pkill, kill processes by GID(Group ID)
$ pkill -9 -G $GID
# 6.Using pkill, kill processes by PPID(Parent Process ID)
$ pkill -9 -p $PPID
# 7.Using pkill, kill processes by terminal
$ pkill -9 -t $terminal
# 8.Using pkill, kill processes by process name
$ pkill -9 -x $process_name
# 9.Using pkill, kill processes by session
$ pkill -9 -s $sess