bash shell笔记6 脚本控制
知识体系:
#回顾信号功能
#隐藏在背景中
#在没有控制台的情况下运行
#做得更好
#准确无误的运行
#从头开始
前面运行脚本的方式都是在命令行界面运行,实际上还有运行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程序,所以通过这方法可以终止进程。
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
[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 ]
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
我只是在上面的例子中最后添加了移除捕获的一行,结果脚本退出的捕获被移除了,就没有了捕获信息显示了。
2、以后台模式运行脚本
有些shell脚本在执行中需要等待漫长时间,而且终端回话无法执行其他操作,这个时候就可以使得shell放置到后台运行。
2.1、以后台模式运行
这个很简单就得意实现,只要在运行脚本时在命令后面附带一个&符号即可。
[root@wzp
~]# cat 6.2test
#!/bin/bash
count=1
while [ $count -le 5 ]
do
echo "loop #$count"
sleep 3
count=$[ $count + 1 ]
done
[root@wzp ~]# ./6.2test &
[5] 7348
[root@wzp ~]# loop #1
loop #2
loop #3
loop #4
loop #5
[5]
Done
./6.2test
通过这方法就可以到程序放到后台运行,控制台便可以进行其他操作。
所以可以借用这种方法运行多个程序。
3、在不使用控制台的情况下运行脚本
一个程序运行过程默认情况下会随着中断回话的退出而中断。这个时候就可以借用nohup命令来使得阻塞任何发送到进程的SIGHUP信号。
[root@wzp
~]# cat 6.2test
#!/bin/bash
count=1
while [ $count -le 5 ]
do
echo "loop #$count"
sleep 3
count=$[ $count + 1 ]
done
[root@wzp ~]# nohup ./6.2test &
[2] 7877
[root@wzp ~]# nohup: appending output to
“nohup.out”
[root@wzp ~]#
[2]-
Done
nohup ./6.2test
因为nohup将进程和终端断开,所以进程没有STDOUT和STDERR输出链接。nohup命令将自动把这两类消息重定向到nohup.out这个自动新创建的文件中去:
[root@wzp ~]# cat nohup.out
loop #1
loop #2
loop #3
loop #4
loop #5
这个文件的内容跟命令行运行进程输出是完全一样的!
4、作业控制
shell运行的进程可以通过ctrl+z中断,利用kill终止进程,可以使用发送SIGCONT信号重启停止的进程。对于重启、停止。终止、恢复作业的操作就叫做作业控制。
4.1、查看作业
通过jobs命令可以直接查看shell处理的当前作业,看例子:
[root@wzp
~]# nohup ./6.2test &
[1] 8477
[root@wzp ~]# nohup: appending output to
“nohup.out”
[root@wzp ~]# nohup ./6.2test &
[2] 8479
[root@wzp ~]# nohup: appending output to
“nohup.out”
[root@wzp ~]# jobs
[1]-
Running
nohup ./6.2test &
[2]+
Running
nohup ./6.2test &
[root@wzp ~]# jobs
[1]-
Done
nohup ./6.2test
[2]+
Done
nohup ./6.2test
我运行两次同样的脚步程序到后台,然后通过jobs查看,显示running状态,等到脚步运行结束再次jobs查看即可显示已完成状态。
[root@wzp
~]# nohup ./6.2test &
[2] 8594
[root@wzp ~]# nohup: appending output to
“nohup.out”
[root@wzp ~]# jobs
[2]+
Running
nohup ./6.2test &
[root@wzp ~]# kill 8594
[root@wzp ~]# jobs
[2]+
已终止
nohup ./6.2test
当脚本一开始运行到后台会显示了PID号8594,当脚本还没运行结束我kill掉进程,也可以通过jobs查看出进程已经被kill了。
4.2、重新启动停止的作业
我们可以通过ctrl+z暂停进程,当要重新启动停止的作业时可以通过使用带有作业编号的bg命令,看例子:
[root@wzp
~]# nohup ./6.2test
nohup: appending output to “nohup.out”
[1]+
Stopped
nohup ./6.2test
[root@wzp ~]# jobs
[1]+
Stopped
nohup ./6.2test
[root@wzp ~]# bg 1
[1]+ nohup ./6.2test &
[root@wzp ~]# jobs
[1]+
Running
nohup ./6.2test &
[root@wzp ~]# jobs
[1]+
Done
nohup ./6.2test
先是把程序放到后台运行,然后马上暂停了进程运行,通过jobs即可查看。然后通过bg命令附带作业编号1重启进程。注意:作业编号在我一开始暂停进程的时候就显示了[1]。
上面的bg命令重启的进程后是放到进程去运行的。如果你想把它放到显示屏运行,即可以使用带编号的fg命令,看例子:
[root@wzp
~]# ./6.2test
loop #1
loop #2
[1]+
Stopped
./6.2test
[root@wzp ~]# fg 1
./6.2test
loop #3
loop #4
loop #5
运行一半的程序被暂停后,通过fg
1又可以调到命令行运行下去了。
5、使脚本更好的运行
linux是一个多任务操作系统,内核负责为系统中运行的每个进程分配CPU时间。而CUP中一次就能运行一个进程,因此内核轮流向每个进程分配CPU时间。从shell启动的所有进程在linux系统上的调度优先级都是相同的。调度优先级是内核相对其他进程分配某一个进程的CPU时间量。
调度优先级是一个整数值,从-20(最高优先级)到+20(最低优先级),默认情况下,bash
shell启动所有优先级为0的进程
5.1 nice命令
nice命令可以在启动命令时设置它的调度优先级,要让命令在更低的优先级下运行,可以使用-n选项。看个例子:
[root@wzp ~]# nice -n 10 ./6.2test &
[1] 9888
这样子,该程序就运行在10优先级下了。还有一点注意的是我是通过root超级用户设定脚本运行的优先级别,如果设置在更低的优先级,对于普通用户即可操作,并且一般是属于该脚本程序的用户所有者。但是普通用户无法设置脚本再更高的优先级别下运行。看例子:
[testuser@wzp
~]$ ll
总计 8
-rwxr--r-- 1 testuser root 107 02-15 20:00 6.2test
[testuser@wzp ~]$ nice -n 10 ./6.2test &
[1] 10164
[testuser@wzp ~]$
loop #1
loop #2
loop #3
运行指定在低优先级是没问题的!
[testuser@wzp
~]$ nice -n -10 ./6.2test &
[1] 10186
[testuser@wzp ~]$ nice: cannot set niceness: 权限不够
[1]+ Exit
1
nice -n -10 ./6.2test
设定在高优先级下运行报权限不够的错误信息!
5.2、renice命令
有使用需要更改系统中已运行的优先级,就可以使用renice命令,例子:
[root@wzp
~]# nohup ./6.2test &
[1] 10369
[root@wzp ~]# nohup: appending output to
“nohup.out”
[root@wzp ~]# renice -10 -p 10369
10369: old priority 0, new priority -10
原先我设定脚本再后台运行,并且默认是0的优先级别。通过renice命令指定-10更高的优先级别,并且通过-p加PID号设定,从log信息我们知道旧的调度优先级被修改了。
6、准确无误的运行
shell脚本有时候需要设定在给定的时间运行,特别是半夜,等业务量没有那么忙的时候往往是SA反而忙碌的时候,我们很容易可以想到通过计划任务是实现这一需求,这里头主要有三种方式:
*at 命令
*batch 命令
*cron 表格
6.1、使用at命令调度作业
对于at命令的具体使用方面这里就不罗嗦了,可以看下网上的资料或者linux的复习进阶一讲述。其命令格式、日期格式都是需要注意的。
这里讲述下通过运行atd和sendmail应用程序来获取作业输出:
由于linux使用提交作业的用户的电子邮箱地址作为STDOUT和STDERR,所以任何以STDOUT和STDERR为目的地的输出都通过电子邮件发送给用户。
当需要制定运行某个文件的at计划,可以附带-f选项,如:
at -f testfile xx:xx
当制定好at命令后可以通过atq命令查看计划列表;
如果要删除已经制定好的计划列表可以通过atrm命令,附带计划number。
6.2、使用batch命令
batch命令跟at命令不太相同,我们知道at命令是在一个指定的时间运行计划好的命令,而batch则是安排脚本在系统使用率低的时候运行。如果linux处于高负荷下运行,那么batch命令就会延迟提交作业的运行。跟at命令类型的地方是命令的格式,可以通过-f参数从文件中读取,默认从STDIN读取。
6.3、调度定期脚本
如果需要脚本在每天、每周、每月的一个特定时间执行脚本,就可以使用cron程序调度需要运行的作业。cron程序在后台运行,它从特殊表格中查找需要调度运行的作业。
对于cron表格的一些命令格式、时间格式,构建cron表格等内容就不说了,这个直接去找网上资料或者看linux复习进结一的计划任务即可。
不过有点挺搞的提及下:系统管理员想在每个月的最后一天执行脚本,那么cron表格应该怎么写么?我们知道每个月的最后一天有可能是28、29、30、31,那么应该怎么判断这一天呢?答案:
这里可以借助添加if-then语句,用date命令检查明天是否1号即可解决问题,具体的cron表格内容如下:
* * * * * if [ `date +%d -d tomorrow` = 01 ]; then ;
command
通过这种方法就可以判定每个月最后一天啦~\(≧▽≦)/~
bash shell笔记6 脚本控制的更多相关文章
- bash shell笔记1 脚本基础知识
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/505644 * ...
- bash shell笔记3 结构化命令二
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/513601 三 ...
- LINUX SHELL 笔记 01: 脚本
root@iZwz:~/labs# vim myfirst root@iZwz:~/labs# cat myfirst #!/bin/bash clear echo "this is my ...
- bash shell笔记7 创建函数
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/525126 知 ...
- bash shell笔记5 显示数据
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/521455 知 ...
- bash shell笔记4 处理用…
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/521448 知 ...
- bash shell笔记2 结构化命令
二.使用结构化命令 知识内容: # 改变命令流 # 使用if-then逻辑 # 嵌套if-then # 测试条件 # 高级if-then功能 许多程序在脚本命令之间需要某些逻辑控制流,有些命令允许脚本 ...
- Bash shell 笔记总结(一) 转自http://www.bubuko.com/infodetail-509992.html,谢谢原作者
本文是上课笔记总结,涉及细节知识点会在以后文章说明! bash脚本编程: 脚本程序:解释器解释执行: shell: 交互式接口:编程环境: shell: 能够提供一些内部命令,并且能通过PATH环境变 ...
- linux笔记:shell基础-概述和脚本执行方式
什么是shell: linux使用的默认shell是Bash: shell脚本的后缀名为.sh,shell脚本的第一行#!/bin/bash 不是注释,而是标识这是一个shell脚本,因为linux并 ...
随机推荐
- 【python】没有root权限的时候安装Python package
下载相关位置的包 1.首先在git上下载对应的包: 搜索package github,找到地址.使用 git clone https://xxx.git 命令 2.使用python setup.py ...
- 关于SQL Sever连接问题
错误: 与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法访问服务器.请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接. (provider: ...
- [置顶]
【机器学习PAI实践五】机器学习眼中的《人民的名义》
一.背景 最近热播的反腐神剧"人民的名义"掀起来一波社会舆论的高潮,这部电视剧之所能得到广泛的关注,除了老戏骨们精湛的演技,整部剧出色的剧本也起到了关键的作用.笔者在平日追剧之余, ...
- Go语言的序列化与反序列化(gob)
encoding/gob包实现了高效的序列化,特别是数据结构较复杂的,结构体.数组和切片都被支持. 实现代码如下://定义一个结构体type Student struct { Name string ...
- (一)Nginx正向代理与反向代理
引言:身为前端开发人员来说对于Nginx的作用或许很少听到,这个东西是后端使用的,Nginx对前端而言意味着什么,有什么用呢?大白会整理出几篇文章给大家细细道来. 1.正向代理的概念 正向代理,也就是 ...
- PS基础教程[1]如何制作微信泡泡
PS是很多朋友都很喜欢额一款图像处理软件,我们可以使用PS制作很多的效果,本系列经验教程的起源就来源于知道中这位朋友问的微信泡泡如何使用,下面就来简单的分享一下. 微信泡泡制作方法 有很多的方法可以制 ...
- LG3195 [HNOI2008]玩具装箱TOY
题意 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为\(1\cdots N\) ...
- homebrew的安装与使用
homebrew的安装:http://jingyan.baidu.com/article/fec7a1e5ec30341190b4e7e5.html 引用segfaultment上面的回答 没这个说法 ...
- unity drawcall测试
unity引擎影响drawcall的元素(使用Quad和Cube对比测试) 1.相机的background(没有渲染元素区域的颜色),4Verts.2Tris.1SetPass calls: ...
- A SQLiteConnection object for database '/data/data/.../databases/....db' was leaked!
详细异常: A SQLiteConnection object for database '/data/data/.../databases/....db' was leaked! Please ...