本文共 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!