一些控制脚本的方式:向脚本发送信号、修改脚本优先级,在脚本运行时切换到运行模式

16.1 处理信号

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

也可以通过对脚本进行编程,使其在收到特定信号时执行某些命令。从而控制脚本的操作。

16.1.1 重温Linux信号

比如下面这些常见的:

信号   值         描述

1    SIGUP     挂起进程

2    SIGINT     终止进程

3    SIGOUT    停止进程

9    SIGKILL    无条件终止进程

15    SIGTERM   尽可能终止进程

……

默认情况下,bash shell会忽略收到的任何SIGOUT(3)和SIGTERM(15)。

但是会处理收到的SIGHUP(1)和SIGINT(2)。

shell会将这些信号传给shell脚本程序来处理,而shell脚本的默认行为是忽略这些信号。

可以在脚本中加入识别信号的代码,并执行命令来处理信号。

16.1.2 生成信号

bash shell允许用键盘上的组合键生成两种进本的linux信号。

1.中断进程

Ctrl+c会生成SIGINT信号。会发送给当前在shell中运行的所有进程。

2.暂停进程

在进程运行时暂停进程,无需终止它。让程序继续保留在内存中,并能从上次停止的位置继续运行。

有时打开了一个关键的系统文件锁,这就比较危险了。

但是这样可以在不终止进程的情况下能深入脚本内部一窥究竟。

Ctrl+z 会生成一个SIGTSTP信号,停止shell中运行的任何进程。

步骤:

$sleep 30

按下Ctrl + Z

$ls -l --forest

S列(进程状态)中,停止进程的状态为T。

$exit

这样会退出。

16.1.3 捕获信号

也可以不忽略信号,在信号出现时捕获它们并执行相应命令。

trap命令允许你来指定脚本要监看并从shell中拦截的linux信号。

如果脚本收到了trap中列出的信号,该信号不再由shell处理,而是交由本地处理。

命令格式: trap commands signals

16.1.4 捕获脚本退出

在脚本退出时进行捕获。

在trap命令后加上EXIT信号就行了。

按下Ctrl+C 和 自己运行退出都能被捕获到。

例子:

  1 #!/bin/bash

  2 trap " echo 'GoodBye everyone!!!'" EXIT # 捕获脚本退出时的信号

  3 # trap " echo 'sorry! I have trapped Ctrl+C'" SIGINT # 对应16.1.3 的例子。捕获Ctrl+C

  4 echo "This is Begin ......"

  5 count=1

  6 while [ $count -le 10 ]

  7 do

  8         echo "    count = $count"

  9         sleep 1

 10         count=$[ $count + 1 ]

 11 done

 12 echo "This is End!"

16.1.5 修改或移除捕获

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

修改了信号捕获后,脚本处理信号的方式就会发生变化。

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

trap -- SIGINT

也可以用单破折号来恢复信号的默认行为。

例子:

  1 #!/bin/bash

  2 trap " echo 'I have trapped Ctrl+C'" SIGINT

  3 echo "This is Begin ......"

  4 count=1

  5 while [ $count -le 5 ]

  6 do

  7         echo "  First loop: $count"

  8         sleep 1

  9         count=$[ $count + 1 ]

 10 done

 11 #trap – SIGINT # 恢复默认行为

 12 #trap – SIGINT # 删除设置好的捕获

 13 trap " echo 'I modified the trap'" SIGINT # 在这个位置也捕获一下,以后捕获到就会走这里

 14 count=1

 15 while [ $count -le 5 ]

 16 do

 17         echo "    Second loop: $count"

 18         sleep 1

 19         count=$[ $count + 1 ]

 20 done

 21

 22 echo "This is End!"

16.2 以后台模式运行脚本

有的脚本可能要运行很长时间,你不想一直在命令行界面等着,这时你也没法做别的事情。这时候就需要后台运行脚本了。

ps命令可以看到很多进程都不是运行在终端显示器上的,这些就是后台进程。

在后台模式下,进程运行不会和终端会话上电STDIN STDOUT STDER关联。

16.2.1 后台运行脚本

命令后面加个取地址符就好了

例如:

$./test &

显示的第一行是shell分配给后台进程的作业号[]里面的。后面那个是进程的PID

后台进程结束时,会在终端显示一条消息表明已经结束了。

注意:后台进程运行时,任然会使用终端显示器来显示STDOUT和STDERR消息。

所以可以将后台运行的程序的STDOUT和STDERR进行重定向。

16.2.2 运行多个后台作业

同时启动多个后台作业就可以了。

在终端会话中使用后台进程要注意,ps命令的输出中,每一个后台进程都和终端会话(pts/0)终端联系在一起。如果终端会话退出,那么后台进程也会退出。

16.3 在非控制台下运行脚本

需求:在终端启动脚本,让脚本一直运行到结束,即使退出了终端会话。

nohup命令可以做到。它运行了另外一个命令来阻断所有发送给该进程的SIGHUP信号。这样终端退出时脚本也不会退出。

命令格式:

$nohup ./test &

nohup会自动将STDOUT和STDERR的消息重定向到一个名为nohup.out的文件中。

如果在同一个目录运行两次,第二次会追加到nohup.out。

16.4 作业控制

重启停止的进程需要向其发送一个SIGCONT信号。

启动、停止、终止、恢复作业这些功能统称为作业控制

16.4.1 查看作业

jobs命令允许查看shell当前正在处理的作业。

命令格式:

$jobs

用法:

$./test > log.txt &  # 后台运行一个作业,不能马上结束

$jobs  # 这里就可以看到了

还有一些其他的选项:

-l 列出PID和作业号   -r 只列出运行中的作业  -s 只列出停止的作业 ……….

例子:

  1 #!/bin/bash

  2 echo "Script process ID:$$"

  3 count=1

  4 while [ $count -le 10 ]

  5 do

  6         echo "count = $count"

  7         sleep 1

  8         count=$[ $count + 1 ]

  9 done

 10

 11 echo "This is end, Bye!!!"

运行多次:

带加号+的:当做默认作业(被当成作业控制命令的操作对象)

默认作业完成后,执行下一个作业(带减号-的)。任何时候都只有一个带加号和一个带减号的作业。

还可以这样:

用kill杀死当前默认作业。那么值钱带减号的就变成默认作业了。

16.4.2 重启停止的作业

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

用bg命令实现。

bg 加上作业号。

不加作业号可以重启默认作业。

当有多个作业时必须加上作业号。

实例:

Ctrl + Z停止作业。

注意:bg 重启后是后台作业,ctrl + c 是接受不到的。

前台模式重启作业,可用带作业号的fg命令。

比如:fg 2

例子就像上面一样,把bg换成fg就好了。

16.5 调整谦让度

在多任务操作系统中,内核负责将cpu时间分配给系统上运行的每一个进程。

调度优先级是内核分配给进程的CPU时间。

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

调度优先级是个整数值(-20 -- +19)。

-20是最高优先级,+19是最低优先级。

可以通过nice命令来提高或者降低优先级。

16.5.1 nice命令

可以设置启动时的调度优先级。

nice –n 来指定新的优先级别。

比如:

$nice –n 10 ./test > test.txt &

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

可以通过ps命令查看谦让度值(NI列)

$ps –p 3634 –o pid,ppid,ni,cmd   //  这里3634是进程对应的PID

还可以这样:省掉-n,在破折号后面跟上优先级就好了。

$nice -10 ./test > test.txt &

如果想提高优先级会失败,nice组织普通系统用户来提高命令的优先级。

16.5.2 renice命令

改变系统上已经运行的命令的优先级。可以通过renice实现。

比如:

$./test &

… 此时已经运行了,假设PID是3454

$renice –n 10 –p 3454  // 这样会自动更新当前运行进程的优先级。

注意:

只能对属于你的进程执行renice

只能通过renice降低进程的优先级

root用户可以通过renice来调度任意进程的优先级

16.6 定时运行作业

可以在某个预设时间运行脚本。

方法:at命令和cron表

16.6.1 用at命令来计划执行作业

at命令会将作业提交到队列中,指定shell何时运行该作业。at的守护进程atd会以后台模式运行,检查作业队列来运行作业。

atd会检查某个特殊目录(通常在/var/spool/at)来获取at命令提交的作业。默认情况下,atd会没60s检查一下这个目录,如果设置的运行时间和当前时间匹配,atd守护进程就会运行此作业。

这个只能指定时间运行,不能循环运行。

1.at命令的基本格式

at [-f filename] time

-f指定脚本名

time 指定了linux系统何时运行该作业。 at可以识别多种不同的时间格式。

使用at命令该作业会被提交到作业队列(job quene

针对不同的优先级,存在26种不同的作业队列,作业队列通常用小写字母a-z和A-Z来指代。

作业队列的字母排序越高,作业运行的优先级就越低(nice值越大)。

默认情况下at的作业会被提交到a作业队列。可以用-q参数指定不同的队列字母。

2.获取作业的输出

显示器不会关联到该作业,取而代之的是linux将提交该作业的用户的电子邮件地址作为STDOUT和STDERR。任何标准输出和标准错误都会通过邮件发送给用户。

如果没有关联电子邮件就无法获得输出,所以最好在脚本中对STDERR和STDOUT进行重定向

at的-M选项用来屏蔽作业产生的输出信息。

例子:就是重定向的例子。这里不写了。

3. 列出等待的作业

atq命令可以查看系统中有哪些作业在等待。

我的atq是自己装的,好像不会默认安装。

作业列表列出了作业号,系统运行该作业的日期以及所在的作业队列。上面的都在a队列。

4.删除作业

atrm删除等待中的作业,后面接作业号。

比如:

$atrm 3

16.6.2安排需要定期执行的脚本

可以设置每天指定时间运行一次,或者每周一次,每月一次。

cron程序可以安排定期执行的作业。cron程序会在后台运行并检查一个特殊的表,来获取已安排执行的作业。

1.cron时间表

采用一种特别的格式来指定作业何时运行。格式如下:

min hour dayofmounth month dayofweek command

dayofmounth:指定月份中的日期值(1-31

dayofweek:表示指定周的第几天

cron时间表允许你用特定值,取值范围(比如1~5)或者通配符*来指定条目。

比如:

每天10:15运行命令:15 10 * * * command

每周1的4:15运行:15 4 * * 1 command

每个月第一天12点:0 12 1 * * command

command需要指定要运行命令或脚本的全路径名,后面还可以接参数和重定向符号

2. 构建cron时间表

crontab –l 列出已有的cron时间表。默认情况下,用户的cron时间表并不存在。

要为cron时间表添加条目可以用-e选项。

$cron -e

如果要设置定时运行自己的程序,就需要添加条目了。

3.浏览cron目录

有4个预配置的cron脚本目录可以供我们使用。hourly,dialy,monthly,weekly。

查看:

$ls /etc/eron.*ly

假如脚本需要每天运行一次,将它复制到daily就可以了。其他的同理

4.anacron程序

cron程序最大的问题是假定linux系统是24小时一直开机的。除非是服务器,否则不一定会24小时一直在。

关机的时候就有可能会错过某些需要运行的作业。系统开机时cron程序不会运行那些错过的作业。anacron程序就是为了解决这个问题的。

如果anacron知道某个作业错过了执行时间,它会尽快运行该作业。anacron程序只会处理位于cron目录的程序,比如/etc/cron.monthly。

anacron不会处理执行时间需求小于一天的脚本

16.6.3 使用新的shell启动脚本

如果每次运行脚本的时候都能够启动一个新的bash shell,将会非常的方便。(这个我理解不来)

补充第六章的内容

用户登录bash shell需要运行的启动文件。

$HOME/.bash_profile

$HOME/.bash_login

$HOME/.profile

每次启动一个新shell时,bash shell都会运行.bashrc文件。

假如在.bashrc最后加echo “I am new shell”。这样每打开一个新的shell都会运行这个。

《Linux命令行与shell脚本编程大全》第十六章 控制脚本的更多相关文章

  1. 《Linux命令行与shell脚本编程大全》 第六章环境变量

    很多程序和脚本都通过环境变量来获取系统信息.存储临时数据和配置信息. 6.1 什么是环境变量: bash shell用一个叫环境变量(environment variable)的特性来存储有关shel ...

  2. Linux命令行与shell脚本编程大全.第3版(文字版) 超清文字-非扫描版 [免积分、免登录]

    此处免费下载,无需账号,无需登录,无需积分.收集自互联网,侵权通知删除. 点击下载:Linux命令行与shell脚本编程大全.第3版 (大小:约22M)

  3. 《Linux命令行与shell脚本编程大全 第3版》创建实用的脚本---11

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  4. 《Linux命令行与shell脚本编程大全 第3版》高级Shell脚本编程---47

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  5. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---57

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  6. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---57

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  7. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---56

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  8. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---55

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  9. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---54

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

随机推荐

  1. spring MVC 环境搭建

    绿色版Spring MVC(单纯的springMVC) 一.导包,为了获取请求数据多添加一个包 二.web.xml配置 <?xml version="1.0" encodin ...

  2. LeetCode 628. Maximum Product of Three Numbers (最大三数乘积)

    Given an integer array, find three numbers whose product is maximum and output the maximum product. ...

  3. LeetCode 380. Insert Delete GetRandom O(1) (插入删除和获得随机数 常数时间)

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  4. 26.Linux-网卡驱动(详解)

    1.描述 网卡的驱动其实很简单,它还是与硬件相关,主要是负责收发网络的数据包,它将上层协议传递下来的数据包以特定的媒介访问控制方式进行发送, 并将接收到的数据包传递给上层协议. 网卡设备与字符设备和块 ...

  5. java调用oracle数据库发布WebService

    package com.hyan.service; import java.io.FileInputStream;import java.sql.Connection;import java.sql. ...

  6. 读书笔记-你不知道的JS上-词法作用域

    JS引擎 编译与执行 Javascript引擎会在词法分析和代码生成阶段对运行性能进行优化,包含对冗余元素进行优化(例如对语句在不影响结果的情况下进行重新组合). 对于Javascript来说,大部分 ...

  7. Python CRM项目一

    开发环境: 语言Python3.X以上 MTV WEB框架 Django 前端框架 jQuery+bootstrap 数据库 MySQL 运行环境 安装Python3.x 安装Django 除IE8以 ...

  8. git常用命令集合

    git命令 git init:创建一个仓库并在目录下新建一个.git的文件(初始化一个git仓库) 注:.git文件在工作区,是一个隐藏文件(用ls -ah命令查看),但是它不算工作区,而是git 的 ...

  9. Spring IOC容器分析(2) -- BeanDefinition

    上文对Spring IOC容器的核心BeanFactory接口分析发现:在默认Bean工厂DefaultListableBeanFactory中对象不是以Object形成存储,而是以BeanDefin ...

  10. maven构建SSM--pox.mxl

    最近在做项目,把maven构建SSM的pom.xml文件内容小结一下: 在console中输入如下内容,使用maven创建java web项目: mvn archetype:generate -Dgr ...