16. 控制脚本

本文介绍了如何在Linux环境中控制shell脚本,包括处理信号如Ctrl+C和Ctrl+Z,后台模式运行脚本,使用nohup使其在非控制台下运行,以及作业控制和调整进程的谦让度。此外,还详细讲解了如何使用trap命令捕获脚本退出信号和修改信号处理,以及使用at和cron命令进行定时任务的设置。
摘要由CSDN通过智能技术生成

16 控制脚本

16.1 处理信号

16.1.1 重温Linux信号
在这里插入图片描述
在这里插入图片描述
16.1.2 生成信号
中断进程:Ctrl+C组合键会发送SIGINT信号,停止shell中当前运行的进程。
暂停进程:Ctrl+Z组合键会生成一个SIGTSTP信号,停止shell中运行的任何进程。

$ sleep 100 
^Z 
[1]+  Stopped                 sleep 100

[1]是shell分配的作业号,如果有已停止的作业,在使用exit退出shell时,bash会提醒你有未停止的作业。使用ps -l显示当前作业的状态,显示T说明命令要么被跟踪,要么被停止了。
显示当前指令
使用kill -9 pid号发送一个SIGKILL信号来终止它,第一次没有提示,第二次告诉你已经杀死了。
在这里插入图片描述
16.1.3 捕获信号
trap命令允许你来指定shell脚本要监看并从shell中拦截的Linux信号。如果脚本收到了trap命令中列出的信号,该信号不再由shell处理,而是交由本地处理。

#!/bin/bash 
# Testing signal trapping 
# 
trap "echo ' Sorry! I have trapped Ctrl-C'" SIGINT  #相当于一个中断打印函数,每次捕获到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 捕获脚本退出
使用trap捕获退出信号EXIT就行,只要脚本退出就会执行这个指令。

trap "echo Goodbye..." EXIT

16.1.5 修改或移除捕获
trap -- SIGINT是恢复信号的默认行为,重新定义就可以修改捕获

trap "echo ' Sorry... Ctrl-C is trapped.'" SIGINT   #第一次设置
trap "echo ' I modified the trap!'" SIGINT   #第二次设置修改
trap -- SIGINT  #移除信号捕获

16.2 以后台模式运行脚本

16.2.1 后台运行脚本
当脚本在运行时,你没法在终端会话里做别的事情。在后台模式中,进程运行时不会和终端会话上的STDINSTDOUT以及STDERR关联。对应只需要在文件运行后加上&就可以。

$ ./test4.sh & 
[1] 3231

(在我的ubuntu系统下,如果不输入新的指令,会一直等待不会自动显示结束消息,暂时没有搞清楚原因,之后补充)

这种模式下面,会打印出消息到命令行,所以建议重定向STDOUT和STDERR

16.2.2 运行多个后台脚本
就是在终端中以后台模式运行多个脚本

16.3 在非控制台下运行脚本

有时你会想在终端会话中启动shell脚本,然后让脚本一直以后台模式运行到结束,即使你退出了终端会话。

nohup ./文件名称 &  

由于nohup命令会解除终端与进程的关联,进程也就不再同STDOUTSTDERR联系在一起。为了保存该命令产生的输出,nohup命令会自动将STDOUTSTDERR的消息重定向到一个名为nohup.out的文件中。

16.4 作业控制

启动、停止、终止以及恢复作业的这些功能统称为作业控制。
16.4.1 查看作业
编写test5.sh内容

#!/bin/bash
echo "Script PID:$$ "
count=1
while [ $count -le 10 ]
do
  sleep 10
  count=$[ $count + 1 ]
done

echo "End of script..."

运行两次脚本,第一次使用Ctrl+Z停止,第二次正常运行将信息打印到指定文件中。

$./test5.sh  
$./test5.sh > test5.out &

使用jobs显示当前作业,注意这里有一个默认进程(指的是最后启动的进程)用+号区别
显示结果
相关的选项命令
在这里插入图片描述
16.4.2 重启停止的作业
后台进程模式启动: 使用bg指令重启的是默认作业,多个作业需要使用bg 作业号启动指定作业。
前台进程模式启动: 使用fg 作业号指令

16.5 调整谦让度

调度优先级(scheduling priority)是内核分配给进程的CPU时间(相对于其他进程)。其是个整数值,从-20(最高优先级)到+19(最低优先级)。

在Linux系统中,由shell启动的所有进程的调度优先级默认都是相同的。 默认情况下,bash shell以优先级0来启动所有进程。数字越大越难得到CPU的运行时间。

16.5.1 nice命令
nice -n 优先级 或者 nice -优先级 指定作业优先级运行某个脚本文件,例如:nice -n 10 ./test5.sh > test5out &

但是不允许普通系统用户提高作业的优先级,例如上面使用10运行了作业,下面如果用-10更改已经运行的test5.sh作业级别,如nice -n -10 ./test5.sh > test5out &会被系统拒绝。

16.5.2 renice命令
更改已运行命令的优先级,可以利用指定PID改变优先级。命令格式:renice -n 优先级别 -p pid号

存在以下限制:

  1. 只能对属于你的进程执行renice;
  2. 只能通过renice降低进程的优先级;
  3. root用户可以通过renice来任意调整进程的优先级。

16.6 定时运行作业

Linux系统提供了多个在预选时间运行脚本的方法:at命令和cron
16.6.1 用at命令计划执行作业
at的守护进程atd会以后台模式运行,检查作业队列来运行作业。atd守护进程会检查系统上的一个特殊目录(通常位于/var/spool/at)来获取用at命令提交的作业。

默认情况下,atd守护进程会每60秒检查一下这个目录。有作业时,如果作业时间跟当前时间匹配,atd守护进程就会运行此作业。

1. at命令的格式
-f指定文件名称

at [-f filename] time

在你使用at命令时,该作业会被提交到作业队列。针对不同优先级,存在26种不同的作业队列。作业队列通常用小写字母a~z和大写字母A~Z来指代。

2. 获取作业的输出
test6.sh脚本相关内容

#!/bin/bash
echo "This script ran at $(date +%b%d,%T)" > testing.out  #最好对输出进行重定向
sleep 5
echo "This is the script's end..." >> testing.out

使用at命令分配作业运行安排,如果内部没有重定向STDOUTSTDERR,也不会打印消息,因为会使用sendmail应用程序发送邮件,没有安装就无法获取输出。-M可以屏蔽输出。

at -M -f test6.sh now

3. 列出等待的作业
使用atq显示作业号、系统运行该作业的日期和时间及其所在的作业队列。

4.删除作业
使用atrm 作业号删除指定作业

16.6.2 安排需要定期执行的脚本
1. cron指令
at命令在预设时间安排脚本执行非常好用,但如果你需要脚本在每天的同一时间运行或是每周一次、每月一次呢?

min hour dayofmonth month dayofweek command

2.cron时间表
crontab -l列出已有的cron时间表

3.浏览cron目录
如果你创建的脚本对精确的执行时间要求不高,用预配置的cron脚本目录会更方便。有4个基本目录:hourly、daily、monthly和weekly,复制到对应的目录就会按照对应规则执行。

4.anacron目录
cron程序的唯一问题是它假定Linux系统是7×24小时运行的。除非将Linux当成服务器环境来运行,否则此假设未必成立。

如果anacron知道某个作业错过了执行时间,它会尽快运行该作业。这意味着如果Linux系统关机了几天,当它再次开机时,原定在关机期间运行的作业会自动运行。

period delay identifier command

period条目定义了作业多久运行一次,以天为单位。identifier条目是一种特别的非空字符串。

16.6.3 使用新shell启动脚本
如果每次运行脚本的时候都能够启动一个新的bash shell(即便只是某个用户启动了一个bash shell),将会非常的方便。

每次启动一个新的shell的时候,bash shell都会运行.bashrc文件,因此可以将shell启动时需要执行的脚本放在.bashrc文件中实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值