第十六章:控制腳本
本章內(nèi)容
處理信號
以后臺模式運行腳本
禁止掛起
作業(yè)控制
修改腳本優(yōu)先級
腳本執(zhí)行自動化
16.1 處理信號
16.1.1 重溫Linux信號
Linux系統(tǒng)信號
Linux利用信號與運行在系統(tǒng)中的進程進行通信
可以使用信號來停止/啟動/終止進程
可以通過對腳本進行編程剔难,使其在收到特定信號時執(zhí)行某些命令饶唤,從而控制shell腳本
默認情況下,bash shell會忽略收到的任何3和15信號
但是bash shell會處理1和2信號
常見的Linux系統(tǒng)信號
信號:值:描述
1:SIGHUP:掛起進程
2:SIGINT:終止進程
3:SIGQUIT:停止進程
9:SIGKILL:無條件終止進程
15:SIGTERM:盡可能終止進程
17:SIGSTOP:無條件停止進程洼冻,但不是終止進程
18:SIGTSTP:停止或暫停進程宣虾,但不終止進程
19:SIGCONT:繼續(xù)運行停止的進程
16.1.2 生成信號
1.中斷進程
使用Ctrl+C組合鍵會生成2(SIGINT)信號惯裕,并將其發(fā)送給當前在shell中運行的所有進程
執(zhí)行命令
sleep 100
^C
注:^代指Ctrl鍵
2.暫停進程
使用Ctrl+Z組合鍵會生成18(SIGTSTP)信號,停止shell中運行的任何進程
執(zhí)行命令
sleep 100
^Z
當按鍵Ctrl+Z組合鍵時绣硝,bash shell會給出如下提示
[1]+ Stopped sleep 100
方括號中的數(shù)字時shell分配的作業(yè)號(job number)
shell將shell中運行的每個進程稱為作業(yè)蜻势,并為每個作業(yè)分配唯一的作業(yè)號
如果shell回話中有已停止的作業(yè),在退出shell時鹉胖,bash會提醒你
常用操作
ps -l
查看已停止的作業(yè)握玛,在S列中(進程狀態(tài))顯示T的為已停止的作業(yè)
kill -9 PID
終止指定PID的作業(yè),終止已停止作業(yè)的PID
通俗來講甫菠,就是殺掉進程
16.1.3 捕獲信號
命令格式:trap commands signals
命令說明:使用trap命令來指定shell腳本要監(jiān)看并從shell中攔截的Linux信號
使用trap命令來忽略SIGINT信號
編寫test1.sh腳本
#!/bin/bash
trap "echo 'Sorry!I have trappend 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"
16.1.4 捕獲腳本退出
捕獲shell腳本的退出EXIT信號
編寫test2.sh腳本
#!/bin/bash
trap "echo Goodbye..." EXIT
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count+1 ]
done
16.1.5 修改或移除捕獲
修改信號捕獲挠铲,腳本仍然會根據(jù)最初的trap命令進行處理
編寫test3.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 "Loop #$count"
sleep 1
count=$[ $count+1 ]
done
在trap和信號列表之間加上兩個破折號刪除已設(shè)置好的捕獲并恢復(fù)默認行為
編寫test3b.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
#
# Remove the trap
trap -- SIGINT
echo "I just removed the trap"
#
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count+1 ]
done
敲門:也可以在trap命令后使用單破折號來恢復(fù)信號的默認行為。單破折號和雙破折號都可以正常發(fā)揮作用
16.2 以后臺模式運行腳本
16.2.1 后臺運行腳本
在命令后加個&符以后臺模式運行shell腳本
編寫test4.sh腳本
#!/bin/bash
count=1
while [ $count -le 10 ]
do
sleep 1
count=$[ $count+1 ]
done
執(zhí)行命令
./test4.sh &
然后顯示[1] 3231
方括號中的表示后臺進程的作業(yè)號寂诱,后面的數(shù)字為進程的進程ID(PID)
當后臺進程運行時拂苹,它仍然會使用終端顯示器來顯示STDOUT和STDERR消息
編寫test5.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"
當腳本在后臺模式運行時,腳本的輸出和輸入的命令以及命令輸出全都混在了一起痰洒,最好是將后臺運行的腳本的STDOUT和STDERR進行重定向瓢棒,避免雜亂的輸出
16.2.2 運行多個后臺作業(yè)
可以使用&符號的方法在命令行提示符下同時啟動多個后臺作業(yè)
使用ps命令查看所有腳本的運行狀態(tài)
在終端會話中使用后臺進程時一定要小心,當退出終端時带迟,后臺進程也會退出
16.2.3 在非控制臺下運行腳本
命令格式:nohup ./test1.sh &
命令說明:使用nohup命令在終端會話中啟動shell腳本音羞,并讓腳本一直以后臺模式運行到結(jié)束,即使退出了終端會話仓犬,shell腳本也會一直運行
執(zhí)行命令
nohup ./test1.sh &
cat nohup.out
說明
使用nohup啟動shell腳本時嗅绰,腳本會忽略終端會話發(fā)過來的SIGHUP信號
由于nohup命令會解除終端與進程的關(guān)聯(lián)缚去,進程也就不在同STDOUT和STDERR關(guān)聯(lián)
nohup命令會自動將STDOUT和STDERR的消息重定向到當前目錄下名為nohup.out的文件中
如果使用nohup命令運行了另一個腳本技矮,則該腳本的輸出會被追加到已有的nohup.out文件中
16.4 作業(yè)控制
啟動/停止/終止以及恢復(fù)作業(yè)的這些功能統(tǒng)稱為作業(yè)控制
16.4.1 查看作業(yè)
使用jobs命令查看shell當前正在處理的作業(yè),腳本$$變量顯示Linux系統(tǒng)分配給該腳本的PID
編寫test10.sh腳本
#!/bin/bash
#
echo "Script Process ID: $$"
#
count=1
while [ $count -le 10 ]
do
echo "Loop #$count"
sleep 10
count=$[ $count + 1 ]
done
#
echo "End of script..."
#
執(zhí)行命令
./test10.sh > test10.out &
查看作業(yè)
jobs
查看作業(yè)的PID
jobs -l
jobs命令參數(shù)
參數(shù):描述
-l:列出進程的PID以及作業(yè)號
-n:只列出上次shell發(fā)出的通知后改變了狀態(tài)的作業(yè)
-p:只列出作業(yè)的PID
-r:只列出運行中的作業(yè)
-s:只列出已停止的作業(yè)
jobs命令輸出中的加號和減號
帶加號的作業(yè)會被當做默認作業(yè)
在使用作業(yè)控制命令時件相,如果未在命令行指定任何作業(yè)號叽躯,
該作業(yè)會被當做作業(yè)控制命令的操作對象
當前的默認作業(yè)完成處理后财边,帶減號的作業(yè)成為下一個默認作業(yè)
任何時候都只有一個帶加號的作業(yè)和一個帶減號的作業(yè),
不管shell中有多少個正在運行的作業(yè)
16.4.2 重啟停止的作業(yè)
命令格式:bg 作業(yè)號
命令說明:以后臺模式重啟指定作業(yè)
命令格式:fg 作業(yè)號
命令說明:以前臺模式重啟指定作業(yè)
16.6 定時運行作業(yè)
16.6.1 用at命令來計劃執(zhí)行作業(yè)
1.at命令的格式
命令格式:at [-f filename] time
命令說明:使用-f參數(shù)指定需要執(zhí)行的腳本文件的文件名点骑,time參數(shù)制定了什么時候運行
多種不同的時間格式
標準的小時和分鐘格式酣难,比如10:15
AP/PM指示符谍夭,比如10:15PM
特定可命名時間,比如now憨募,noon紧索,midnight或teatime(4PM)
標準日期格式,比如MMDDYY菜谣,MM/DD/YY或DD.MM.YY
文本日期珠漂,比如Junl4或Dec25,加不加年份均可
也可以指定時間增量
當前時間+25min
明天10:15PM
10:15+7天
2.獲取作業(yè)的輸出
在Linux系統(tǒng)上運行時尾膊,顯示器并不會關(guān)聯(lián)到該作業(yè)媳危。Linux系統(tǒng)會將STDOUT或STDERR的輸出通過郵件系統(tǒng)發(fā)送給用戶
編寫test13.sh腳本
#!/bin/bash
echo "This script ran at $(date +%B%d,%T)"
echo
sleep 5
echo "This is the script end..."
執(zhí)行命令
at -f test13.sh now
使用-M選項來屏蔽作業(yè)產(chǎn)生的輸出信息
編寫test13b.sh
#!/bin/bash
echo "This script ran at $(date +%B%d,%T)" > test13b.out
echo >> test13b.out
sleep 5
echo "This is the script end..." >> test13b.out
執(zhí)行命令
at -M -f test13b.sh now
cat test13b.out
3.列出等待的作業(yè)
atq命令查看系統(tǒng)中有哪些作業(yè)在等待,顯示作業(yè)列表
作業(yè)列表中顯示了作業(yè)號冈敛,系統(tǒng)運行該作業(yè)的日期和時間及其所在的作業(yè)隊列
4.刪除作業(yè)
命令格式:atrm 作業(yè)號
命令說明:使用atrm刪除指定作業(yè)
16.6.2 安排需要定期執(zhí)行的腳本
1.cron時間表
命令格式:min hour dayofmonth month dayofweek command
命令說明:cron時間表采用一種特別的格式來指定作業(yè)何時運行
格式說明
dayofweek:文本(mon待笑,tue,wed抓谴,thu滋觉,fri,sat齐邦,sun)或數(shù)值(0為周日,6為周六)
dayofmonth:表示月份中的日期值(1~31)
cron實例
在每天的10:15運行一個命令
15 10 * * * command
在每周一4:15PM運行的命令
15 16 * * 1 command
在每個月的第一天中午12點執(zhí)行命令
00 12 1 * * command
在每個月的最后一天執(zhí)行命令
00 12 * * * if [‘date +%d -d tomorrow’ = 01]; then;command
說明:在每天中午12點檢查是不是當月的最后一天第租,如果是措拇,cron將會運行該命令
執(zhí)行命令
15 10 * * * /home/zc/test/unit16/test4.sh > test4.out
2.構(gòu)建cron時間表
Linux提供了 crontab來處理cron時間表,使用cron時間表來運行安排好的任務(wù)
命令格式:crontab -l
命令說明:使用crontab -l列出已有的cron時間表
3.瀏覽cron目錄
如果創(chuàng)建的腳本對精確的執(zhí)行時間要求不高慎宾,則可以使用預(yù)配置的cron腳本目錄
四個基本目錄
hourly:每小時執(zhí)行
daily:每天執(zhí)行
monthly:每月執(zhí)行
weekly:每周執(zhí)行
執(zhí)行命令
ls /etc/cron.*ly
16.6.3 使用新shell啟動腳本
每次啟動一個新shell時丐吓,bash shell都會運行$HOME/.bashrc文件
驗證
在$HOME/.bashrc文件的最后加入:echo "I'm in a new shell"
然后保存,關(guān)閉shell終端
重新打開shell終端時趟据,可以看見該提示語
16.7 小結(jié)
本章主要講解了linux中的信號控制券犁,以后臺模式執(zhí)行腳本,指定時間執(zhí)行腳本汹碱,修改腳本的優(yōu)先級等粘衬。