Linux的脚本运行是在外面赋予执行权限,而后再进行运行的。可是这并非惟一一种的运行方式。本章介绍控制shell脚本再系统的运行方式以及运行时间的不一样方法。shell
Linux进程之间的通信使用的就是信号。这些信号包括中止、启动和终止进程。也能够经过信号控制脚本运行。后端
Linux和应用程序能够生成30多个Linux信号,常见信号以下:bash
默认状况下,脚本葫芦收到的任何SIGOUIT(3)和SIGTERM(15)信号。可是会处理任何SIGHUP(1)和SIGINT(2)信号。服务器
bash shell收到SIGHUP(1)会退出。收到SIGNINT信号,shell当即终端。app
一、终断进程ide
使用 ctrl+c 生成SIGINIT信号。工具
sleep 100
二、暂停进程oop
ctrl + z 生成STGSTP信号。中止进程,进程保留在内存中,可以从中止的地方继续执行;测试
使用 ctrl + z 组合键以下:spa
其中[1],1表明做业(job),shell脚本以做为为单位在进程中运行,每一个做业都有本身的做业编号;
此时,经过exit 退出shell的时候,就会提示:There are stopped jobs.
经过ps查看做业状态:
其中 STAT 中 T 表示做业状态,表示该做业正在被跟踪或者已经中止;再次输入exit就能够中止做业;
同时,也能够发送信号9 SIGKILL信号来终止做业;
kill -9 20605
这样就直接终止了PID为20605的进程
trap命令能够指定可以经过shell脚本监控和拦截的Linux信号。若是脚本收到trap命中列出的信号,它将保护盖信号不被shell处理,并在本地处理它。
trap使用格式:trap commands signals
#!/bin/bash # testing output in a background job trap "echo Haha" SIGINT SIGTERM echo "This is a test program" count=1 while [ $count -le 10 ] do echo "Loop #$count" sleep count=$[ $count + 1 ] done echo "This is the end of the test program"
每次使用 ctrl+c 组合监视,脚本执行在trap命令中指定的echo语句,而不是忽略信号并允许shell中止脚本。
shell脚本退出的时候也能够捕获信号。只须要向trap命令添加EXIT信号;
#!/bin/bash # trapping the script exit trap "echo byebye" EXIT count=1 while [ $count -le 5 ] do echo "Loop #$count" sleep 3 count=$[ $count + 1 ] done
使用ctrl+c组合键发送SIGINT信号,脚本将退出,可是在脚本退出以前,shell将执行trap命令;
要移除捕获,使用破折号做为命令和想要恢复正常行为的信号列表。
#!/bin/bash # removing a set trap trap "echo byebye" EXIT count=1 while [ $count -le 5 ] do echo "Loop #$count" sleep 3 count=$[ $count + 1 ] done trap - EXIT echo "I just remved the trap"
脚本正常运行结束,这忽略EXIT信号,可是若是中途ctrl+c终止信号,则已让裕兴EXIT信号;
咱们的进程能够运行在后台,然后台运行进程与STDIN、STDOUT以及STDERR无关;
如下咱们要介绍如何在Linux系统中之后台模式运行脚本。
在命令后加上一个 & 符号,就将进程运行到后端了
./test1 &
[1] 19582 #显示做业号 和进程号
脚本输出结果,会与单前运行的命令结果混合在一块儿,等脚本再后台执行完成之后,会有有提示:
[1]+ Done ./test
表示后台进程运行完成;
./test1 & ./test1 & ./test1 &
能够经过ps命令查看
每一个后台进程都关联一个终端会话(pts/0)终端,退出终端会话,就会腿很粗后台运行的进程;
通常状况下,咱们更加但愿关闭控制台,可是后台进程继续运行,如何实现呢?
有时须要从终端会话启动shell脚本,而后让脚本再结束以前之后台模式运行,即便退出终端会话也是如此。可使用nohup命令实现;
nohup命令运行另外一个命令阻塞发送到进程的任何SIGHUP信号。这能够防止在退出终端会话时退出进程。
$nohup ./test1 & [1] 19831 $nohup: appending output to 'nohup.out'
#nohup命令将脚本胡烈任何终端会话发送的SIGHUB信号。由于nohup命令将进程和终端断开,因此进程没有STDOUT和STDERR输出链接。为了接受命令生成的任何输出,nohup命令自动将STDOOUT和STDERR消息重定向到称为nohup.out的文件
cat nohup.out
重启、中止、终止、恢复做业操做叫作做业控制(job control)。使用做业控制能够彻底控制进程在shell环境中的运行方式。
#!/bin/bash # testing job control echo "This is a test program $$" # $$ 变量显示Linux系统分配给脚本的PID count=1 while [ $count -le 10 ] do ehco "Loop #$count" sleep 10 count=$[ $count + 1 ] done echo "This is the end of the test program"
./test4
./test4 > test4out &
jobs #经过jobs命令查看后台运行中止的进程
jobs命令参数:
在jobs显示的内容中:+ 表明默认做业,- 表明当前默认做业结束后将成为默认做业的做业;
bg 命令,提供后台模式中从新启动做业的功能;
$ bg 2 [2]+ ./test4 & Loop #2 $ Loop #3 Loop #4 $ jobs
fg 命令,听前台模式下做业从新启动的功能;
$ jobs [1]+ Stopped ./test4 $ fg 1 ./test4
默认状况下,shell在CPU上运行的调度优先级(scheduling priority)都相同。调度优先级是内核相对其余进程分配给某一进程CPU时间量。
调度优先级从-20(最高)到+20(最低)。默认请看下bash shell启动全部优先级为0的进程。
而 nice 命令则是用来更改进程优先级的。
nice -n 选定新的优先级水平:
$ nice -n 10 ./test4 > test4out & [1] 29476
增长进程优先级:
$ nice -n -10 ./test4 > test4out & [1] 29501 $ nice: cannot set priority: Permission denied #报错,nice不允许普通用户增长命令优先级 [1]+ Exit 1 nice -n -10 ./test4 > test4out
更改已经在系统中运行的命令优先级。这就须要使用人ice命令。
$./test4 > test4out & [1] 29504 $ ps al $ renice 10 -p 29504 $ ps al
renice的限制:
一、只能对拥有进程使用renice命令;二、只能使用renice命令将进程调至更低的优先级;三、根用户可使用renice命令将任何进程调至任何优先级;
指定脚本的预运行时间:一、at命令;二、batch命令;三、cron表格;
at提交到一个队列,在后台运行使用atd命令来完成;
atd命令其实是检查/var/spool/at文件,默认60s检查一次。若是有做业,且与运行时间匹配,则执行;
一、at命令格式
at [ -f filename ] time
time格式:10:15(标准时间) AM/PM提示符好比 10:15PM 具体时间:now、noon、midnight、teatime(4PM)
time的日期格式:MMDDYY、MM/DD/YY或者DD.MM.YY 文本日期格式:Jul 4或者Dec 25 没有年份也能够 时间增量:Now + 25 minutes 或者 10:15 + 7 days
at命令会将做业提交到做业列表中等待执行。也可使用 -q 参数有限执行该做业
二、获取做业输出
将捕获到的做业输出,做为电子邮件发送出来
#!/bin/bash # testing the at command time=`date +%T` echo "This script ran at $time" echo "This is the end of the script" >&2
at -f test5 12:08
>N 1 rich@testbox Sat Nov 3 12:08 14/474 "Output from your job
三、列出排队的做业
atq 命令可以查看那些做业在排队
at -f test5 10:15 at -f test5 2007-11-04 10:15 at -f test5 4PM at -f test5 1PM tomorrow atq
四、移除做业
atrm 命令移除做业
atrm 8 #指定做业号便可 atq
这个命令是安排脚本再系统使用率低时运行。若是系统处于高负载,batch的做业则会推迟提交。知道系统负载下降;
batch [ -f filename ] [ time ]
crontab 调度列表,按期执行脚本程序。
一、cron表格
格式以下:
min hour dayofmonth month dayofweek command
dayofweek:mon tue wed thu fri sat sun
dayofmonth:1-31
month:1-12
例如:15 10 * * * command #10:15
例如:15 16 * * 1 command #每周一的16:15
例如:00 12 1 * * command #每个月的1号,中午12点
二、构建cron表格
crontab -l #查看表格内容
三、anacron程序
若是使用cron调度做业运行是Linux系统处于关闭状态,则做业将没法运行。cron程序没法在系统打开后从新运行错过的做业。为了解决这个问题,许多Linux发行版本提供了anacron程序。
anacron在系统应为关机后没有执行既定的脚本的话,在系统恢复之后,会补上;
anacron的程序使用给本身的表格,位于/etc/anacrontab中;
anacron表格格式:
period delay identifier command
period:定义做业应该间隔多久运行一次
delay:指定在anacron程序肯定应该运行一个命令以后须要多久才会实际运行该命令;
identifier:为一个非空字符串,能够惟一表示日志消息和错误电子邮件中的做业。
让脚本再Linux系统已启动或者用户启动新的bash shell会话时并自动运行。
做为系统管理员,在系统启动的时候有些操做,在启动系统的时候就须要执行如下,好比:重置自定义日志文件或者启动自定义应用程序等。
在将shell脚本设置为启动时自动启动以前,须要了解下Linux启动过程的工做方式。Linux在启动时按照必定的顺序启动脚本,了解该过程将有助于您让脚本按照预期的方式运行。
一、启动过程
Linux系统的第一启动程序 init 程序 /sbin/init 它的进程为PID 1;
init程序读取 /etc/inittab 文件。根据不一样级别来启动程序;Linux启系统的运行级别:
Linux常见的运行级别是5。而后就是运行级别为3。
Linux系统经过rc脚本肯定以哪一种运行级别启动那些程序。启动脚本是启动应用程序的shell脚本,为运行的程序提供必要的环境的脚本。
系统脚本程序放在/etc/rc.d目录中;
二、定义脚本
最好不要弄乱Linux发型版中的任何启动脚本文件。发行版Linux系统提供了一些工具自动在添加服务器应用程序时构建这些脚本,手动更改这些脚本可能会出现问题。而有一个脚本程序就是用来给用户指定启动系统时须要运行的程序的:
每一个用户都包含两个主目录文件:
一、.bash_profile文件
二、.bashrc文件
新用户登陆、在运行新的shell的时候,就会执行.bash_profile文件。该文件中放置任何您但愿登陆时运行的脚本。
每次启动新的shell时(包括新用户登陆时)运行.bashrc文件。能够向主目录的.bashrc文件添加一个简单的echo语句,而后启动一个新shell以测试该特性:
$ bash
This is a new shell!!
若是是但愿每一个用户都运行这个脚本,则将脚本程序卸载/etc/bashrc文件中;