控制脚本
发布日期:2021-06-30 15:02:55 浏览次数:2 分类:技术文章

本文共 4251 字,大约阅读时间需要 14 分钟。

contents

脚本不一定只能以实模式下在命令行界面上直接运行,还可以有一些选项能够控制脚本,向脚本发送信号、修改脚本的优先级以及在脚本运行时切换到运行模式。

处理信号

Linux 利用信号与运行在系统中的进程进行通信。

重温 Linux 信号

信号 名称 描述
1 HUP 挂起
2 INT 终止
3 QUIT 结束运行
9 KILL 无条件终止
11 SEGV 段错误
15 TERM 尽可能终止
17 STOP 无条件停止运行,但不终止
18 TSTP 停止或暂停,但继续在后台运行
19 CONT 在 STOP 或 TSTP 之后恢复执行

停止进程和终止进程不同:停止进程会让程序继续保留在内存中,并能从上次停止的位置继续运行。

默认情况下, bash shell 会忽略收到的任何 SIGQUIT(3) 和 SIGTERM(5) 信号,所以 交互时 shell 才不会被意外终止,但是 shell 会处理收到的 SIGHUP(1) 和 SIGINT(2) 信号。

如果 shell 收到了 SIGHUP 信号,它就会退出,但在退出前,它会将 SIGHUP 信号传给所有该 shell 的启动进程。
shell 会将这些信号传给 shell 脚本程序来处理,shell 脚本的默认行为是忽略这些信号。它们可能会不利于脚本执行,所以需要在脚本中加入信号识别的代码。

生成信号

中断进程

Ctrl + C 生成 SIGINT 信号,终止 shell 中当前运行的进程。

暂停进程

Ctrl + Z 生成 SIGTSTP 信号,停止/暂停 shell 中运行的任何进程,停止进程会让程序继续保留在内存中,并能从上次停止的位置继续运行。

可以使用 ps 命令来查看已停止的作业,ps 命令将已停止作业的状态显示为 T。

捕获信号

可以在信号出现时捕获它们并执行其他命令。trap 命令允许你来指定 shell 脚本要监看并从 shell 中拦截的 Linux 信号。如果脚本收到了 trap 命令中列出的信号,该信号不再由 shell 处理,而是交由本地处理。

trap commands signals
#!/bin/bash#...trap "echo ' Sorry! I have trapped Ctrl+C' " SIGINT#...

在脚本运行的时候,如果试图 Ctrl + C 来终止,那么就会弹出 Sorry! I have trapped Ctrl+C 来拒绝终止操作,而不是处理该信号允许停止脚本。

捕获脚本退出

可以捕获 shell 脚本退出时的信号。

#!/bin/bash#...trap "echo Goodbye " EXIT#...

这样当脚本运行到正常退出位置时,shell 就会就会执行 trap 命令所指定的命令,如果提前退出脚本(Ctrl+C),同样会被 trap 捕获。

修改或移除捕获

如果需要在脚本的不同位置进行不同的捕获处理,只需重新使用带有选项的 trap 命令。

#!/bin/bash#...trap "SIGINT " SIGINT#...trap "SIGINT " SIGINT#...

如果一个信号是在捕获被修改前接收到的,那么脚本仍然会根据最初的 trao 命令进行处理。

也可以删除已设置好的捕获,只需要在 trap 命令 与希望恢复默认行为的信号列表之间加上两个破折号就行了。

#!/bin/bash#...trap "SIGINT " SIGINT#...trap -- SIGINT

也可以在 trap 命令之后使用单破折号来恢复信号的默认行为。

移除信号捕获后,脚本按照默认行为来处理 SIGINT 信号,也就是终止脚本运行。

以后台模式运行脚本

后台运行脚本

以后台模式运行 shell 脚本非常简单。只要在命令后加个 & 就行了,将命令作为系统中的一个独立的后台进程运行。当后台进程运行结束后,会显示结束提示。即使程序在后台运行,仍会使用终端显示器来显示 STDOUT 和 STDERR 消息。

在显示输出的同时,你仍然可以运行命令。当然,为了避免脚本的输出和命令的输出交织在一起,最好将脚本中的 STDIN、STDOUT、STDERR进行重定向。

运行多个后台作业

可以使用 & 符号,将多个命令均置于后台。每次启动新作业时,Linux 系统都会为其分配一个新的作业号和 PID。通过 ps 命令,可以看到所有脚本处于运行状态在 ps 命令的输出中,每一个后台进程都和终端会话联系在一起,如果终端会话退出,那么后台进程也会随之退出。

方括号中的数字是 shell 分配给后台进程的作业号,后面的数字是 Linux 系统分配给进程的进程 ID,Linux 系统上运行的每个进程都必须有一个唯一的 PID。

在非控制台下运行脚本

即使你退出了终端,仍然想让脚本运行,可以使用 nohup 命令实现。

nohup 命令运行了另外一个命令来阻断所有发送给该进程的 SIGHUP 信号。这会在退出终端会话时阻止进程退出。

nohup ./test.sh &

当你使用 nuhup 命令时,如果关闭该会话,脚本会忽略终端会话发过来的 SIGHUP 信号。由于 nohup 命令会解除终端与进程的关联,进程也就不再同 STDOUT 和 STDERR 联系在一起。为了保存该命令产生的输出,nohup 命令会自动将 STDOUT 和 STDERR 的消息重定向到一个名为nohup.out 的文件中。

nohup.out 文件包含了通常会发送到终端显示器上的所有输出。在进程完成运行之后,你可以查看 nohup.out 文件中的输出结果。

作业控制

查看作业

作业控制中的关键命令是 jobs 命令。jobs 命令允许查看 shell 当前正在处理的作业。

脚本用 $$ 变量来显示 Linux 系统分配给该脚本的 PID。

jobs 命令参数:

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

带加号的作业会被当成默认作业,当前的默认作业处理完毕后,带减号的作业成为下一个默认作业。任何时候都只有一个带加号的作业和一个带减号的作业,不管 shell 中有多少个正在运行的作业。

重启停止的作业

可以将停止的作业作为后台进程或前台进程重启。前台进程会接管你当前工作的终端。

要以后台模式重启一个作业(stopped - running),可用 bg 命令加上作业号。
要以前台模式重启作业,可用带有作业号的 fg 命令。
由于作业是以前台模式运行的,直到该作业完成后,命令行界面的提示符才会出现

调整谦让度

在Linux 系统中,由shell启动的所有进程的调度优先级默认都是相同的。

调度优先级是个整数值,-20(最高优先级)- +19(最低优先级),默认情况下,shell 以优先级 0 来启动所有进程。

nice 命令

nice 命令允许你设置命令启动时的调用优先级。只要用 nice -n 命令即可,会改变谦让度值(NI)。

nice -n 10 ./test.sh > test.out &

必须将 nice 命令和要启动的命令放在同一行中。

nice命令组织普通用户来提高命令的优先级。

renice 命令

它允许你指定运行进程的 PID 来改变它的优先级。

renice 命令会自动更新当前运行进程的调度优先级。和 nice 命令一样,renice 命令也有一些限制:

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

定时运行作业

用 at 命令来计划执行作业

安排需要定期执行的脚本

crond 服务管理与访问控制

一般不需要手动开启。

service crond restart # 启动命令chkconfig crond on # 自启动命令

crontab 设置

crontab [选项]
选项 说明
-e 编辑 crontab 定时任务
-l 查询 crontab 任务
-r 删除当前用户所有的 crontab 任务
项目 含义 范围
min 一小时当中的第几分钟 0-59
hour 一天当中的第几个小时 0-23
dayofmonth 一个月当中的第几天 1-31
month 一年中的第几月 1-12
dayofweek 一周当中的星期几 0-7(0和7都代表星期日)
时间 含义
45 22 * * * 命令 在22点45分执行命令
0 17 * * 1 命令 每周1的17点0分执行命令
0 5 1,15 * * 命令 每月1号和15号的凌晨5点0分执行命令
40 4 * * 1-5 命令 每周一到五的凌晨4点40分执行命令
*/10 4 * * * 命令 每天的凌晨4点,每隔10分钟执行一次命令
0 0 1,15 * 1 命令 每月1号和15号,每周1的0点0分都会执行命令

anacron 程序

cron 程序假定 Linux 24小时运行,如果某个作业在cron时间表中安排运行的时间已到,但这时候 Linux 系统处于关机状态,那么这个作业就不会运行。如果某个作业在cron时间表中安排运行的时间已到,但这时候 Linux 系统处于关机状态,那么这个作业就不会被运行,当系统开机时,cron程序不会再去运行那些错过的作业,anacron则会将原定在关机期间运行的作业运行。

使用新 shell 启动脚本

回想下登入bash shell的启动文件,如果你需要每次运行脚本时都启动一个新的bash shell,那么,你需要将登陆时运行的脚本放在启动文件中,基本上,会按照启动文件的顺序找到的第一个文件被运行,其余的文件被忽略(??)

每次启动一个新的 shell,bash shell 都会运行 .bashr文件。.bashrc 文件通常也是通过某个bash启动文件来运行的,因为.bashrc 文件会运行两次:一次是当你登入bash shell时,另一次是当你启动一个bash shell时。如果你需要一个脚本在两个时刻都得以运行,可以把这个脚本放进该文件中。

转载地址:https://jiaming.blog.csdn.net/article/details/104882364 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:毕业设计日志(17)
下一篇:第六章:内置模块(Ⅰ)

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月30日 02时52分24秒