LinuxShell编程六之控制脚本

第十六章:控制脚本

本章内容

处理信号
以后台模式运行脚本
禁止挂起
作业控制
修改脚本优先级
脚本执行自动化

16.1 处理信号

16.1.1 重温Linux信号

Linux系统信号

Linux利用信号与运行在系统中的进程进行通信
可以使用信号来停止/启动/终止进程
可以通过对脚本进行编程,使其在收到特定信号时执行某些命令,从而控制shell脚本
默认情况下,bash shell会忽略收到的任何3和15信号
但是bash shell会处理1和2信号

常见的Linux系统信号

信号:值:描述
1:SIGHUP:挂起进程
2:SIGINT:终止进程
3:SIGQUIT:停止进程
9:SIGKILL:无条件终止进程
15:SIGTERM:尽可能终止进程
17:SIGSTOP:无条件停止进程,但不是终止进程
18:SIGTSTP:停止或暂停进程,但不终止进程
19:SIGCONT:继续运行停止的进程

16.1.2 生成信号
1.中断进程

使用Ctrl+C组合键会生成2(SIGINT)信号,并将其发送给当前在shell中运行的所有进程

执行命令

sleep 100
^C

注:^代指Ctrl键

2.暂停进程

使用Ctrl+Z组合键会生成18(SIGTSTP)信号,停止shell中运行的任何进程

执行命令

sleep 100
^Z

当按键Ctrl+Z组合键时,bash shell会给出如下提示

[1]+  Stopped sleep 100
方括号中的数字时shell分配的作业号(job number)
shell将shell中运行的每个进程称为作业,并为每个作业分配唯一的作业号
如果shell回话中有已停止的作业,在退出shell时,bash会提醒你

常用操作

ps -l
查看已停止的作业,在S列中(进程状态)显示T的为已停止的作业
kill -9 PID
终止指定PID的作业,终止已停止作业的PID
通俗来讲,就是杀掉进程

16.1.3 捕获信号

命令格式:trap commands signals
命令说明:使用trap命令来指定shell脚本要监看并从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 修改或移除捕获

修改信号捕获,脚本仍然会根据最初的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和信号列表之间加上两个破折号删除已设置好的捕获并恢复默认行为

编写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命令后使用单破折号来恢复信号的默认行为。单破折号和双破折号都可以正常发挥作用

16.2 以后台模式运行脚本

16.2.1 后台运行脚本

在命令后加个&符以后台模式运行shell脚本

编写test4.sh脚本

#!/bin/bash
count=1
while [ $count -le 10 ]
do
    sleep 1
    count=$[ $count+1 ]
done

执行命令

./test4.sh &

然后显示[1] 3231
方括号中的表示后台进程的作业号,后面的数字为进程的进程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 运行多个后台作业

可以使用&符号的方法在命令行提示符下同时启动多个后台作业
使用ps命令查看所有脚本的运行状态
在终端会话中使用后台进程时一定要小心,当退出终端时,后台进程也会退出

16.2.3 在非控制台下运行脚本

命令格式:nohup ./test1.sh &
命令说明:使用nohup命令在终端会话中启动shell脚本,并让脚本一直以后台模式运行到结束,即使退出了终端会话,shell脚本也会一直运行

执行命令

nohup ./test1.sh &
cat nohup.out

说明

使用nohup启动shell脚本时,脚本会忽略终端会话发过来的SIGHUP信号
由于nohup命令会解除终端与进程的关联,进程也就不在同STDOUT和STDERR关联
nohup命令会自动将STDOUT和STDERR的消息重定向到当前目录下名为nohup.out的文件中
如果使用nohup命令运行了另一个脚本,则该脚本的输出会被追加到已有的nohup.out文件中

16.4 作业控制

启动/停止/终止以及恢复作业的这些功能统称为作业控制

16.4.1 查看作业

使用jobs命令查看shell当前正在处理的作业,脚本$$变量显示Linux系统分配给该脚本的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..."
#

执行命令

./test10.sh > test10.out &
查看作业
jobs
查看作业的PID
jobs -l

jobs命令参数

参数:描述
-l:列出进程的PID以及作业号
-n:只列出上次shell发出的通知后改变了状态的作业
-p:只列出作业的PID
-r:只列出运行中的作业
-s:只列出已停止的作业

jobs命令输出中的加号和减号

带加号的作业会被当做默认作业
在使用作业控制命令时,如果未在命令行指定任何作业号,
    该作业会被当做作业控制命令的操作对象
当前的默认作业完成处理后,带减号的作业成为下一个默认作业
任何时候都只有一个带加号的作业和一个带减号的作业,
    不管shell中有多少个正在运行的作业

16.4.2 重启停止的作业

命令格式:bg 作业号
命令说明:以后台模式重启指定作业
命令格式:fg 作业号
命令说明:以前台模式重启指定作业

16.6 定时运行作业

16.6.1 用at命令来计划执行作业

1.at命令的格式

命令格式:at [-f filename] time
命令说明:使用-f参数指定需要执行的脚本文件的文件名,time参数制定了什么时候运行

多种不同的时间格式

标准的小时和分钟格式,比如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.获取作业的输出

在Linux系统上运行时,显示器并不会关联到该作业。Linux系统会将STDOUT或STDERR的输出通过邮件系统发送给用户

编写test13.sh脚本

#!/bin/bash
echo "This script ran at $(date +%B%d,%T)"
echo
sleep 5
echo "This is the script end..."

执行命令

at -f test13.sh now

使用-M选项来屏蔽作业产生的输出信息

编写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

执行命令

at -M -f test13b.sh now
cat test13b.out

3.列出等待的作业

atq命令查看系统中有哪些作业在等待,显示作业列表
作业列表中显示了作业号,系统运行该作业的日期和时间及其所在的作业队列

4.删除作业

命令格式:atrm 作业号
命令说明:使用atrm删除指定作业

16.6.2 安排需要定期执行的脚本

1.cron时间表

命令格式:min hour dayofmonth month dayofweek command
命令说明:cron时间表采用一种特别的格式来指定作业何时运行

格式说明

dayofweek:文本(mon,tue,wed,thu,fri,sat,sun)或数值(0为周日,6为周六)
dayofmonth:表示月份中的日期值(1~31)

cron实例

在每天的10:15运行一个命令
15 10 * * * command
在每周一4:15PM运行的命令
15 16 * * 1 command
在每个月的第一天中午12点执行命令
00 12 1 * * command
在每个月的最后一天执行命令
00 12 * * * if [‘date +%d -d tomorrow’ = 01]; then;command
说明:在每天中午12点检查是不是当月的最后一天,如果是,cron将会运行该命令

执行命令

15 10 * * * /home/zc/test/unit16/test4.sh > test4.out

2.构建cron时间表

Linux提供了 crontab来处理cron时间表,使用cron时间表来运行安排好的任务

命令格式:crontab -l
命令说明:使用crontab -l列出已有的cron时间表

3.浏览cron目录

如果创建的脚本对精确的执行时间要求不高,则可以使用预配置的cron脚本目录

四个基本目录

hourly:每小时执行
daily:每天执行
monthly:每月执行
weekly:每周执行

执行命令

ls /etc/cron.*ly

16.6.3 使用新shell启动脚本

每次启动一个新shell时,bash shell都会运行$HOME/.bashrc文件

验证

在$HOME/.bashrc文件的最后加入:echo "I'm in a new shell"
然后保存,关闭shell终端
重新打开shell终端时,可以看见该提示语

16.7 小结

本章主要讲解了linux中的信号控制,以后台模式执行脚本,指定时间执行脚本,修改脚本的优先级等。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,380评论 0 5
  • 本文全面系统地介绍了shell脚本调试技术,包括使用echo, tee, trap等命令输出关键信息,跟踪变量的值...
    liuzg0734阅读 898评论 0 14
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,738评论 0 10
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 99,238评论 9 467
  • 这阵狂风入室 躁热了清冷的心 煽惑我的热泪滚烫 想你的时候 五脏六腑都掺着苦涩 此间多年 你仍是夏日的明朗 书不尽...
    少女旌一阅读 408评论 1 4