知识体系:
#回顾信号功能
#隐藏在背景中
#在没有控制台的情况下运行
#做得更好
#准确无误的运行
#从头开始
前面运行脚本的方式都是在命令行界面运行,实际上还有运行shell脚本的其他方式,以及中断脚本的运行进程,控制脚本的运行时间都可以实现.
1、处理信号
linux下有各种信号,如停止、启动、终止.通过信号控制shell脚本的运行只需要shell脚本接收来自linux体系特定信号时执行命令即可.
1.1、linux信号回顾
系统和应用程序可以生产30多个linux信号,如下罗列出常用的linux系统信号:
******************************************************
信号 值 描述
1 SIGHUP 挂起进程
2 SIGINT 中断进程
3 SIGQUIT 停止进程
9 SIGKILL 无条件终止进程
15 SIGTERM 如果可能的话终止进程
17 SIGSTOP 无条件停止,但不终止进程
18 SIGTSTP 停止或暂停进程,但不终止
19 SIGCONT 重新启动停止的进程
*******************************************************
默认情况下,bash shell忽略接收到的任何SIGQUIT和SIGTERM信号,以防止交互的shell以外终止.但是bash shell接收任何SIGHUP和SIGINT信号.
1.2、生成信号
1》中断进程
使用ctrl c组合键可以生产SIGINT信号,比如用sleep命令测试:
[root@wzp ~]# sleep 100
如果我不使用组合键,那么控制台就无法进行输入了,一直运行该sleep程序,通过这方法可以终止进程.
拥有帝国一切,皆有可能。欢迎访问phome.net
2》暂停进程
有些进程想暂停而不是终止它,可以使用ctrl z组合键生产SIGTSTP信号
[root@wzp ~]# sleep 100
[1] Stopped sleep 100
看到没有,如果是暂停进程,会有log信息显示stopped的.
如上可以看到中括号里面有一个1数值,这个就是shell分配的作业编号,第一个启动的进程分配作业编号1,第二个启动的进程分配作业编号2,依此类推,如果shell会话中存在停止的作业,退出shell会发出警号的:
[root@wzp ~]# exit
exit
There are stopped jobs.
[root@wzp ~]# exit
退出时说存在着被暂停的作业,不过你再次输入exit可以终止了进程强行退出shell,或者说你可以通过Kill命令发出SIGKILL命令终止它:
[root@wzp ~]# sleep 100
[1] Stopped sleep 100
[root@wzp ~]# sleep 200
[2] Stopped sleep 200
[root@wzp ~]# ps au
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 5007 0.0 0.0 4812 496 pts/0 T 16:19 0:00 sleep 100
root 5009 0.0 0.0 4812 496 pts/0 T 16:19 0:00 sleep 200
root 5025 0.0 0.1 5356 944 pts/0 R 16:19 0:00 ps au
[root@wzp ~]# exit
exit
There are stopped jobs.
[root@wzp ~]# kill -9 5007
[root@wzp ~]# kill -9 5009
[1]- 已杀死 sleep 100
拥有帝国一切,皆有可能。欢迎访问phome.net
[2] 已杀死 sleep 200
这样子通过kill进程号达到终止了进程.
1.3、捕获信号
trap命令可以指定通过shell脚本监控和拦截信号,信号不被shell处理,而在本地处理它,其格式为:
trap commands signals
下面看个例子,使用trap命令来忽略SIGINT和SIGTERM信号的简单示例:
[root@wzp ~]# chmod u x 6.1test
[root@wzp ~]# cat 6.1test
#!/bin/bash
trap "echo you can not stop me!" SIGINT SIGTERM
echo "this is a test program"
count=1
while [ $count -le 10 ]
do
echo "loop #$count"
sleep 3
count=$[ $count 1 ]
done
echo "the program is over"
[root@wzp ~]# ./6.1test
this is a test program
loop #1
loop #2
loop #3
you can not stop me!
loop #4
loop #5
loop #6
you can not stop me!
loop #7
loop #8
you can not stop me!
loop #9
loop #10
the program is over
当如上程序每隔3秒显示一次信息的时候,我通过ctrl c暂停程序的时候,该信号都被忽略了,并且在trap命令下回显echo you can not stop me!内容,并且程序一直执行完毕.由此可以trap命令的强大哈!
1.4、捕获脚本退出
除了上面在shell脚本中捕获信号之外,还可以在shell脚本退出那瞬间捕获,只需要在trap命令后添加EXIT信号,看下例子:
[root@wzp ~]# cat 6.1test
#!/bin/bash
trap "echo yeah, the program is over" EXIT
count=1
while [ $count -le 5 ]
do
echo "loop #$count"
sleep 3
count=$[ $count 1 ]
拥有帝国一切,皆有可能。欢迎访问phome.net
done
[root@wzp ~]# ./6.1test
loop #1
loop #2
loop #3
loop #4
loop #5
yeah, the program is over
当脚本准备退出之际,就会触发trap,并且捕获了EXIT信号显示echo内容
当然,如果你ctrl c终止进程也是会捕获EXIT信号的,暂停进程则不会.
1.5、移除捕获
我们可以使用破折号来移除捕获,shell捕获信号的功能失效,例子:
[root@wzp ~]# cat 6.1test
#!/bin/bash
trap "echo yeah, the program is over" EXIT
count=1
while [ $count -le 5 ]
do
echo "loop #$count"
sleep 3
count=$[ $count 1 ]
done
trap - EXIT
[root@wzp ~]# ./6.1test
loop #1
loop #2
loop #3
loop #4
loop #5
我只是在上面的例子中添加了移除捕获的一行,结果脚本退出的捕获被移除了,就没有了捕获信息显示了.
|