shell脚本编程(三)
文章目录
- tee命令,“T型管道”,将STDIN的数据同时发送到两个目的地。一个是STDOUT,另一个是tee命令行指定的文件名:
tee filename
tee会覆盖原文件,-a参数不会覆盖 - Linux信号
信号 值 描述 1 SIGHUP 挂起进程 2 SIGINT 中断进程 3 SIGQUIT 停止进程 9 SIGKILL 无条件终止进程 15 SIGTERM 如果可能的化终止进程 17 SIGSTOP 无条件停止,但不终止进程 18 SIGTSTP 停止或暂停进程,但不终止它 19 SIGCONT 重新启动停止的进程
默认情况下bash shell会忽略它接收的任何SIGQUIT(3)和SIGTERM(15)信号,以防止交互的shell意外终止。shell会处理它收到的任何SIGHUP(1)和SIGINT(2)信号
- 中断进程:Ctrl+C,生成SIGINT信号
- 暂停进程:Ctrl+Z,生成SIGTSTP信号,停止后程序仍然留在内存中(可以ps命令查看)
trap命令可以指定能够通过shell脚本监控和拦截的Linux信号。:
trap ”commands“ signals(必须用双引号)
trap常用的捕获信号:SIGINT SIGHUP EXIT SIGTERM。
移除捕获可以使用破折号作为命令和想要恢复正常行为的信号列表:
e.g:trap - EXIT
可以在命令后加上**&**符号使后台模式运行shell脚本。也可同时启动任何数量的相同的后台作业。
nohup命令可以使脚本在结束前以后台模式运行:
nohup ./shell脚本 &
运行后shell会给该命令分配一个作业编号,Liunx系统分配一个PID编号。使用nohup后台脚本将忽略任何SIGHUP信号。nohup.out文件包含通常发送到终端监视器的所有输出。(如果使用nohup运行另一个命令,输出将添加到现有的nohup.out文件)脚本使用$$变量显示Linux系统分配给脚本的PID
作业控制:
- jobs可以查看shell处理的当前作业。
- jobs命令输出作业可能带有加号和减号。带有加号的作业被视为默认作业。带有减号的作业是待默认作业。只能有一个加号和一个减号的作业。
bg 作业号
后台程序前台运行。
多任务操作系统中,内核负责为系统中运行的每个进程分配CPU时间。CPU一次只能运行一个进程。默认情况下,从shell启动的所有进程在Linux系统上的调度优先级(scheduling priority)都相同。
调度优先级从-20(最高优先级)到+20(最低优先级),bash shell优先级为0.
调命令优先级:
- nice -n设置启动命令时的优先级
e.g:nice -n 10 ./test >file &
nice不允许普通系统用户增加命令的优先级。 - renice(更改系统中运行的命令优先级,与nice有区别)
e.g:renice 10 -p 24552
:- renice命令自动更新运行进程的调度优先级
- 与nice一样的限制:不允许普通系统用户增加命令的优先级。
- nice -n设置启动命令时的优先级
at命令(给定时间内运行)
at -f filename time #-f指定用于读取命令的文件名(脚本文件)
at可以识别的时间格式:
- 标准的小时和分钟格式,比如10:15
- AM/PM指示符,比如10:15PM
- 具体指定的时间,比如now、noon、midnight、teatime(4PM)
- 如果指定一个过去的时间,at命令将在第二天的那个时间运行作业。
- 标准的日期格式,比如MMDDYY、MM/DD/YY或DD.MM.YY
- 文本日期格式,比如Jul4或Dec 25,有没有年份都可以
- 还可以指定时间增量:
- Now+25minutes
- 10:15PM tomorrow
- 10:15+7days
使用at命令时,作业将提交到作业队列(job queue)中,有26种不同的作业队列可用于不同的优先级水平。使用a到z引用作业队列。默认at作业都提交到作业队列a(最高),使用-q参数改变优先级。
作业在Linux系统运行时,没有与该作业关联的监视器。Linux使用提交作业的用户的电子邮件地址作为STDOUT和STDERR。任何以STDOUT和STDERR为目的地的输出都将通过邮件系统发送给用户(mail)
atq命令能够查看系统中排队的作业
atrm+作业号
可以移除排队的作业。batch命令与at命令稍有不同。安排脚本在系统使用率低时运行。
batch -f filename time
(可以指定batch命令应该尝试运行作业的最早时间)与at命令类似,默认情况下batch命令从STDIN读取命令。
cron:调度需定期运行的作业:corn程序在后台运行,它从特殊表格(cron)中查找需要调度运行的作业。
corn使用特殊格式指定作业运行的时间,表格格式:
min hour dayofmonth month dayofweek command
1 2 3 4
15 10 * * * command #每天10:15运行命令 15 10 * * * 1 command #每周一下午4:15运行 00 12 1 * * command #每个月第一天的中午12点执行 00 12 * * * if[ 'date +%d -d tommorow' =01 ];then;command #在每天12点查看本日是否是该月的最后一天,如果是,它将运行命令
使用crontab命令构建cron表格,列出现有的cron表格:
crontab -l
;向cron表格添加条目:crontab -e
anacron程序使用时间戳确定调度的作业是是否在正确的时间间隔运行。如果它确定某个作业错过了调度的运行时间,它将自动尽快运行该作业。(该特性对于执行例行日志维护的脚本非常有用。)
anacron使用自己的表格(通常:/etc/anacrontab)指定作业。:
period delay identiier command
period定义总也应该多久运行一次,以天为单位。delay项指定在anacron程序确定应该运行一个命令之后需要多长时间才会实际运行该命令。该选项可以为不同的命令这只不同额延迟值,以防所有命令在一打开Linux系统时运行。identifier项是一个位移的非空字符串,可以唯一地识别日志消息和错误电子邮件中的作业。
Linux运行级别
运行级别 描述 运行级别 描述 0 停止 4 未使用 1 单用户模式 5 多用户模式,有网络和图形X Window会话 2 多用户模式,通常没有网络支持 5 多用户模式,有网络和图形X Window会话 3 完全多用户模式,有网络 Linux系统提供了一些脚本文件,用于让脚本在系统启动或者用户启动新的bash shell时运行。rc.local(对于openSusE是boot.local)文件可以列出每次系统启动时启动的脚本。这可以帮助系统管理员在系统启动时运行特定的脚本,以进行系统维护。与此类似.bash_profile和.bashrc文件位于每个用户的主目录,提供一个位置防止与新shell一起运行的脚本和命令。.bash_profile文件在每次用户登陆系统时运行脚本,.basshrc文件按在每个新shell启动时运行脚本。
创建函数
|
|
shell定义函数时,应将定义在前。
shell函数结尾不要使用默认退出状态。可以使用return命令以特定退出状态退出函数。return命令可以使用单个整数值来定义函数退出状态。必须注意避免两个容易发生的错误:
- 函数完成后尽快提取返回值
- 退出状态的取值范围是0-255(变量$?提取)
正如命令输出可以捕获并存放到shell变量中一样,函数输入也可捕获并存放到shell变量中:
e.g:result='shell函数名'(反引号)
这种方法可以返回浮点数和字符串值,所以这种方法能够非常灵活地从函数返回数据。向函数传递参数:bash shell将函数作为小型脚本处理。
函数使用两种类型的变量:
全局变量(这种方法有风险,尤其对多个shell脚本共用的函数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#!/bin/bash #demonstrating a bad use of variable function func1 { temp=$[ $value+5 ] result=$[ $temp*2 ] } temp=4 value=6 func1 echo "The result is $result" if [ $temp -gt $value] then "temp is larger" else "temp is smaller" fi
局部变量:
local temp
向函数传递数组:先用
echo $@
将数组整个传入函数中,随后更具命令行参数重建数组变量。:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
**实例1:** #!/bin/bash #carry variable to function test function testit { local newarray newarray=('echo "$@"') echo "The new array value is ${newwarray[*]}" } mayarray=(1 2 3 4 5) echo "The original array is ${myarrar[*]}" testit ${myarray[*]} **实例2:** #!/bin/bash #adding values in an array funcion addarray { local sum=0 local newarray newarray=('echo "$@"') for value in ${newarray[*]} do [ $sum+$value ] done echo $sum } myarray=(1 2 3 4 5) echo "The original array is :${myarray[*]}" arg1='echo ${myarray[I]}' result='addarray $arg1' echo "The result is $result"
从函数返回数组:(数组的调用和返回关键在于
echo “$@”
)
|
|
- 函数递归
|
|
- 创建库:source命令。source命令在当前shell环境中执行命令,而非创建新shell来执行命令。使用source命令在shell脚本内部运行库文件脚本。这样脚本可以使用这些函数。source有一个短小的别名,成为点操作符。为了在脚本中调用test库文件,只需添加下列命令行:
. ./test
:
|
|