原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://twentyfour.blog.51cto.com/945260/522415

知识体系:

#回顾信号功能

#隐藏在背景中

#在没有控制台的情况下运行

#做得更好

#准确无误的运行

#从头开始

前面运行脚本的方式都是在命令行界面运行,实际上还有运行shell脚本的其他方式,以及中断脚本的运行进程,控制脚本的运行时间都可以实现。

1、处理信号

linux下有各种信号,如停止、启动、终止。通过信号控制shell脚本的运行只需要使得shell脚本接收来自linux体系特定信号时执行命令即可。

1.1、linux信号回顾

系统和应用程序可以生产30多个linux信号,如下罗列出常用的linux系统信号:

******************************************************

信号          
值               
描述

1           
SIGHUP          
挂起进程

2           
SIGINT          
中断进程

3           
SIGQUIT         
停止进程

9           
SIGKILL         
无条件终止进程

15          
SIGTERM         
如果可能的话终止进程

17          
SIGSTOP         
无条件停止,但不终止进程

18          
SIGTSTP         
停止或暂停进程,但不终止

19          
SIGCONT         
重新启动停止的进程

*******************************************************

默认情况下,bash shell忽略接收到的任何SIGQUIT和SIGTERM信号,以防止交互的shell以外终止。但是bash
shell接收任何SIGHUP和SIGINT信号。

1.2、生成信号

1》中断进程

使用ctrl+c组合键可以生产SIGINT信号,比如用sleep命令测试:
[root@wzp
~]# sleep 100
如果我不使用组合键,那么控制台就无法进行输入了,一直运行该sleep程序,所以通过这方法可以终止进程。

2》暂停进程

有些进程想暂停而不是终止它,可以使用ctrl+z组合键生产SIGTSTP信号
[root@wzp
~]# sleep 100

[1]+ 
Stopped                
sleep 100
看到没有,如果是暂停进程,会有log信息显示stopped的。

如上可以看到中括号里面有一个1数值,这个就是shell分配的作业编号,第一个启动的进程分配作业编号1,第二个启动的进程分配作业编号2,依此类推,如果shell会话中存在停止的作业,退出shell会发出警号的:

[root@wzp ~]# exit

exit

There are stopped jobs.

[root@wzp ~]# exit
退出时说存在着被暂停的作业,不过你再次输入exit可以终止了进程强行退出shell,或者说你可以通过Kill命令发出SIGKILL命令终止它:
[root@wzp
~]# sleep 100

[1]+ 
Stopped                
sleep 100

[root@wzp ~]# sleep 200

[2]+ 
Stopped                
sleep 200

[root@wzp ~]# ps au

USER      
PID %CPU %MEM   
VSZ   RSS
TTY     
STAT START   TIME
COMMAND

root     
5007  0.0 
0.0  
4812   496
pts/0   
T   
16:19   0:00 sleep 100

root     
5009  0.0 
0.0  
4812   496
pts/0   
T   
16:19   0:00 sleep 200

root     
5025  0.0 
0.1  
5356   944
pts/0   
R+  
16:19   0:00 ps au

[root@wzp ~]# exit

exit

There are stopped jobs.

[root@wzp ~]# kill -9 5007

[root@wzp ~]# kill -9 5009

[1]- 
已杀死              
sleep 100

[2]+ 
已杀死              
sleep 200
这样子通过kill进程号达到终止了进程。

1.3、捕获信号

trap命令可以指定通过shell脚本监控和拦截信号,使得信号不被shell处理,而在本地处理它,其格式为:

trap commands signals

下面看个例子,使用trap命令来忽略SIGINT和SIGTERM信号的简单示例:

[root@wzp ~]# chmod u+x 6.1test

[root@wzp ~]# cat 6.1test

#!/bin/bash

trap "echo you can not stop me!" SIGINT SIGTERM

echo "this is a test program"

count=1

while [ $count -le 10 ]

do

echo "loop #$count"

sleep 3

count=$[ $count + 1 ]

done

echo "the program is over"

[root@wzp ~]# ./6.1test

this is a test program

loop #1

loop #2

loop #3

you can not stop me!

loop #4

loop #5

loop #6

you can not stop me!

loop #7

loop #8

you can not stop me!

loop #9

loop #10

the program is over
当如上程序每隔3秒显示一次信息的时候,我通过ctrl+c暂停程序的时候,该信号都被忽略了,并且在trap命令下回显echo
you can not stop me!内容,并且程序一直执行完毕。由此可以trap命令的强大哈!

1.4、捕获脚本退出

除了上面在shell脚本中捕获信号之外,还可以在shell脚本退出那瞬间捕获,只需要在trap命令后添加EXIT信号,看下例子:
[root@wzp
~]# cat 6.1test

#!/bin/bash

trap "echo yeah, the program is over" EXIT

count=1

while [ $count -le 5 ]

do

echo "loop #$count"

sleep 3

count=$[ $count + 1 ]

done

[root@wzp ~]# ./6.1test

loop #1

loop #2

loop #3

loop #4

loop #5

yeah, the program is over
当脚本准备退出之际,就会触发trap,并且捕获了EXIT信号显示echo内容

当然,如果你ctrl+c终止进程也是会捕获EXIT信号的,暂停进程则不会。

1.5、移除捕获

我们可以使用破折号来移除捕获,使得shell捕获信号的功能失效,例子:
[root@wzp
~]# cat 6.1test

#!/bin/bash

trap "echo yeah, the program is over" EXIT

count=1

while [ $count -le 5 ]

do

echo "loop #$count"

sleep 3

count=$[ $count + 1 ]

done

trap - EXIT

[root@wzp ~]# ./6.1test

loop #1

loop #2

loop #3

loop #4

loop #5
我只是在上面的例子中最后添加了移除捕获的一行,结果脚本退出的捕获被移除了,就没有了捕获信息显示了。

2、以后台模式运行脚本

有些shell脚本在执行中需要等待漫长时间,而且终端回话无法执行其他操作,这个时候就可以使得shell放置到后台运行。

2.1、以后台模式运行

这个很简单就得意实现,只要在运行脚本时在命令后面附带一个&符号即可。
[root@wzp
~]# cat 6.2test

#!/bin/bash

count=1

while [ $count -le 5 ]

do

echo "loop #$count"

sleep 3

count=$[ $count + 1 ]

done

[root@wzp ~]# ./6.2test &

[5] 7348

[root@wzp ~]# loop #1

loop #2

loop #3

loop #4

loop #5

[5]  
Done                   
./6.2test
通过这方法就可以到程序放到后台运行,控制台便可以进行其他操作。

所以可以借用这种方法运行多个程序。

3、在不使用控制台的情况下运行脚本

一个程序运行过程默认情况下会随着中断回话的退出而中断。这个时候就可以借用nohup命令来使得阻塞任何发送到进程的SIGHUP信号。
[root@wzp
~]# cat 6.2test

#!/bin/bash

count=1

while [ $count -le 5 ]

do

echo "loop #$count"

sleep 3

count=$[ $count + 1 ]

done

[root@wzp ~]# nohup ./6.2test &

[2] 7877

[root@wzp ~]# nohup: appending output to
“nohup.out”

[root@wzp ~]#

[2]- 
Done                   
nohup ./6.2test
因为nohup将进程和终端断开,所以进程没有STDOUT和STDERR输出链接。nohup命令将自动把这两类消息重定向到nohup.out这个自动新创建的文件中去:

[root@wzp ~]# cat nohup.out

loop #1

loop #2

loop #3

loop #4

loop #5
这个文件的内容跟命令行运行进程输出是完全一样的!

4、作业控制

shell运行的进程可以通过ctrl+z中断,利用kill终止进程,可以使用发送SIGCONT信号重启停止的进程。对于重启、停止。终止、恢复作业的操作就叫做作业控制。

4.1、查看作业

通过jobs命令可以直接查看shell处理的当前作业,看例子:
[root@wzp
~]# nohup ./6.2test &

[1] 8477

[root@wzp ~]# nohup: appending output to
“nohup.out”

[root@wzp ~]# nohup ./6.2test &

[2] 8479

[root@wzp ~]# nohup: appending output to
“nohup.out”

[root@wzp ~]# jobs

[1]- 
Running                
nohup ./6.2test &

[2]+ 
Running                
nohup ./6.2test &

[root@wzp ~]# jobs

[1]- 
Done                   
nohup ./6.2test

[2]+ 
Done                   
nohup ./6.2test
我运行两次同样的脚步程序到后台,然后通过jobs查看,显示running状态,等到脚步运行结束再次jobs查看即可显示已完成状态。
[root@wzp
~]# nohup ./6.2test &

[2] 8594

[root@wzp ~]# nohup: appending output to
“nohup.out”

[root@wzp ~]# jobs

[2]+ 
Running                
nohup ./6.2test &

[root@wzp ~]# kill 8594

[root@wzp ~]# jobs

[2]+ 
已终止              
nohup ./6.2test
当脚本一开始运行到后台会显示了PID号8594,当脚本还没运行结束我kill掉进程,也可以通过jobs查看出进程已经被kill了。

4.2、重新启动停止的作业

我们可以通过ctrl+z暂停进程,当要重新启动停止的作业时可以通过使用带有作业编号的bg命令,看例子:
[root@wzp
~]# nohup ./6.2test

nohup: appending output to “nohup.out”

[1]+ 
Stopped                
nohup ./6.2test

[root@wzp ~]# jobs

[1]+ 
Stopped                
nohup ./6.2test

[root@wzp ~]# bg 1

[1]+ nohup ./6.2test &

[root@wzp ~]# jobs

[1]+ 
Running                
nohup ./6.2test &

[root@wzp ~]# jobs

[1]+ 
Done                   
nohup ./6.2test
先是把程序放到后台运行,然后马上暂停了进程运行,通过jobs即可查看。然后通过bg命令附带作业编号1重启进程。注意:作业编号在我一开始暂停进程的时候就显示了[1]。

上面的bg命令重启的进程后是放到进程去运行的。如果你想把它放到显示屏运行,即可以使用带编号的fg命令,看例子:
[root@wzp
~]# ./6.2test

loop #1

loop #2

[1]+ 
Stopped                
./6.2test

[root@wzp ~]# fg 1

./6.2test

loop #3

loop #4

loop #5
运行一半的程序被暂停后,通过fg
1又可以调到命令行运行下去了。

5、使脚本更好的运行

linux是一个多任务操作系统,内核负责为系统中运行的每个进程分配CPU时间。而CUP中一次就能运行一个进程,因此内核轮流向每个进程分配CPU时间。从shell启动的所有进程在linux系统上的调度优先级都是相同的。调度优先级是内核相对其他进程分配某一个进程的CPU时间量。

调度优先级是一个整数值,从-20(最高优先级)到+20(最低优先级),默认情况下,bash
shell启动所有优先级为0的进程

5.1 nice命令

nice命令可以在启动命令时设置它的调度优先级,要让命令在更低的优先级下运行,可以使用-n选项。看个例子:

[root@wzp ~]# nice -n 10 ./6.2test &

[1] 9888
这样子,该程序就运行在10优先级下了。还有一点注意的是我是通过root超级用户设定脚本运行的优先级别,如果设置在更低的优先级,对于普通用户即可操作,并且一般是属于该脚本程序的用户所有者。但是普通用户无法设置脚本再更高的优先级别下运行。看例子:
[testuser@wzp
~]$ ll

总计 8

-rwxr--r-- 1 testuser root 107 02-15 20:00 6.2test

[testuser@wzp ~]$ nice -n 10 ./6.2test &

[1] 10164

[testuser@wzp ~]$

loop #1

loop #2

loop #3
运行指定在低优先级是没问题的!
[testuser@wzp
~]$ nice -n -10 ./6.2test &

[1] 10186

[testuser@wzp ~]$ nice: cannot set niceness: 权限不够

[1]+  Exit
1                 
nice -n -10 ./6.2test
设定在高优先级下运行报权限不够的错误信息!

5.2、renice命令

有使用需要更改系统中已运行的优先级,就可以使用renice命令,例子:
[root@wzp
~]# nohup ./6.2test &

[1] 10369

[root@wzp ~]# nohup: appending output to
“nohup.out”

[root@wzp ~]# renice -10 -p 10369

10369: old priority 0, new priority -10
原先我设定脚本再后台运行,并且默认是0的优先级别。通过renice命令指定-10更高的优先级别,并且通过-p加PID号设定,从log信息我们知道旧的调度优先级被修改了。

6、准确无误的运行

shell脚本有时候需要设定在给定的时间运行,特别是半夜,等业务量没有那么忙的时候往往是SA反而忙碌的时候,我们很容易可以想到通过计划任务是实现这一需求,这里头主要有三种方式:

*at 命令

*batch 命令

*cron 表格

6.1、使用at命令调度作业

对于at命令的具体使用方面这里就不罗嗦了,可以看下网上的资料或者linux的复习进阶一讲述。其命令格式、日期格式都是需要注意的。

这里讲述下通过运行atd和sendmail应用程序来获取作业输出:

由于linux使用提交作业的用户的电子邮箱地址作为STDOUT和STDERR,所以任何以STDOUT和STDERR为目的地的输出都通过电子邮件发送给用户。

当需要制定运行某个文件的at计划,可以附带-f选项,如:

at -f testfile xx:xx

当制定好at命令后可以通过atq命令查看计划列表;

如果要删除已经制定好的计划列表可以通过atrm命令,附带计划number。

6.2、使用batch命令

batch命令跟at命令不太相同,我们知道at命令是在一个指定的时间运行计划好的命令,而batch则是安排脚本在系统使用率低的时候运行。如果linux处于高负荷下运行,那么batch命令就会延迟提交作业的运行。跟at命令类型的地方是命令的格式,可以通过-f参数从文件中读取,默认从STDIN读取。

6.3、调度定期脚本

如果需要脚本在每天、每周、每月的一个特定时间执行脚本,就可以使用cron程序调度需要运行的作业。cron程序在后台运行,它从特殊表格中查找需要调度运行的作业。

对于cron表格的一些命令格式、时间格式,构建cron表格等内容就不说了,这个直接去找网上资料或者看linux复习进结一的计划任务即可。

不过有点挺搞的提及下:系统管理员想在每个月的最后一天执行脚本,那么cron表格应该怎么写么?我们知道每个月的最后一天有可能是28、29、30、31,那么应该怎么判断这一天呢?答案:

这里可以借助添加if-then语句,用date命令检查明天是否1号即可解决问题,具体的cron表格内容如下:

* * * * * if [ `date +%d -d tomorrow` = 01 ]; then ;
command

通过这种方法就可以判定每个月最后一天啦~\(≧▽≦)/~

bash shell笔记6 脚本控制的更多相关文章

  1. bash shell笔记1 脚本基础知识

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/505644 * ...

  2. bash shell笔记3 结构化命令二

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/513601 三 ...

  3. LINUX SHELL 笔记 01: 脚本

    root@iZwz:~/labs# vim myfirst root@iZwz:~/labs# cat myfirst #!/bin/bash clear echo "this is my ...

  4. bash shell笔记7 创建函数

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/525126 知 ...

  5. bash shell笔记5 显示数据

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/521455 知 ...

  6. bash shell笔记4 处理用…

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/521448 知 ...

  7. bash shell笔记2 结构化命令

    二.使用结构化命令 知识内容: # 改变命令流 # 使用if-then逻辑 # 嵌套if-then # 测试条件 # 高级if-then功能 许多程序在脚本命令之间需要某些逻辑控制流,有些命令允许脚本 ...

  8. Bash shell 笔记总结(一) 转自http://www.bubuko.com/infodetail-509992.html,谢谢原作者

    本文是上课笔记总结,涉及细节知识点会在以后文章说明! bash脚本编程: 脚本程序:解释器解释执行: shell: 交互式接口:编程环境: shell: 能够提供一些内部命令,并且能通过PATH环境变 ...

  9. linux笔记:shell基础-概述和脚本执行方式

    什么是shell: linux使用的默认shell是Bash: shell脚本的后缀名为.sh,shell脚本的第一行#!/bin/bash 不是注释,而是标识这是一个shell脚本,因为linux并 ...

随机推荐

  1. SpringCloud教程 | 第九篇: 服务链路追踪(Spring Cloud Sleuth)

    版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 ,博主地址:http://blog.csdn.net/forezp. http://blog.csdn.net/forezp/art ...

  2. Activiti 教程

    Activiti入门教程:http://blog.csdn.net/column/details/activitizhou.html Activiti 5.15 用户手册:http://www.cnb ...

  3. Python基础学习(第6天)

    1.zip函数 1)zip函数在只有一个参数时运作的方式. x = [1, 2, 3] x = zip(x) print x输出:[(1,), (2,), (3,)] 2)zip函数在没有参数时运作的 ...

  4. macOS 下 Visual Studio Code(VSCODE)安装配置及应用

    Visual Studio Code 重新定义了 Code 编辑. 在任何操作系统上编辑和调试应用程序内置 Git 支持1000 种以上的扩展免费和开源 为什么使用VSCODE? 我们来看看以下功能: ...

  5. Android 进阶7:进程通信之 AIDL 的使用

    读完本文你将了解: AIDL 是什么 AIDL 支持的数据类型 AIDL 如何编写 AIDL 实例 创建 AIDL 编写服务端代码 编写客户端代码 运行结果 总结 代码地址 Thanks 记得 201 ...

  6. linux TCP Fast Open开启和测试

    linux上要开启TCP Fast Open,内核版本至少为3.7.0, 且需要设置 /proc/sys/net/ipv4/tcp_fastopen 为3. 开启后,如果有连接进来,使用如下命令查看: ...

  7. Java进阶知识点8:高可扩展架构的利器 - 动态模块加载核心技术(ClassLoader、反射、依赖隔离)

    一.背景 功能模块化是实现系统能力高可扩展性的常见思路.而模块化又可分为静态模块化和动态模块化两类: 1. 静态模块化:指在编译期可以通过引入新的模块扩展系统能力.比如:通过maven/gradle引 ...

  8. 转载Verilog乘法器

    1. 串行乘法器 两个N位二进制数x.y的乘积用简单的方法计算就是利用移位操作来实现. module multi_CX(clk, x, y, result); input clk; input [7: ...

  9. webpack+vue-cli搭建项目 (vue项目重构三)

    在自己的电脑下载了npm 与 node的情况下 可使用vue-cli快速构建vue项目执行命令如下: # 全局安装 vue-cli$ npm install -g vue-cli# 创建一个基于 &q ...

  10. laravel 中config的使用

    在laravel的config中添加配置文件(比如:alipay.php)文件内容为return数组的形式 在方法中使用config()函数获取数据 $config = config('alipay. ...