《Linux命令行与shell脚本编程大全》第十六章 控制脚本

简介: 一些控制脚本的方式:向脚本发送信号、修改脚本优先级,在脚本运行时切换到运行模式  16.1 处理信号 linux利用信号与运行在系统中的进程进行通信。 也可以通过对脚本进行编程,使其在收到特定信号时执行某些命令。

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

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都会运行这个。

目录
相关文章
|
2月前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
413 9
|
Ubuntu Linux 网络安全
Linux系统初始化脚本
一款支持Rocky、CentOS、Ubuntu、Debian、openEuler等主流Linux发行版的系统初始化Shell脚本,涵盖网络配置、主机名设置、镜像源更换、安全加固等多项功能,适配单/双网卡环境,支持UEFI引导,提供多版本下载与持续更新。
289 0
Linux系统初始化脚本
|
2月前
|
算法 Linux Shell
Linux实用技能:打包压缩、热键、Shell与权限管理
本文详解Linux打包压缩技巧、常用命令与原理,涵盖.zip与.tgz格式操作、跨系统传文件方法、Shell运行机制及权限管理,助你高效使用Linux系统。
Linux实用技能:打包压缩、热键、Shell与权限管理
|
2月前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
300 2
|
5月前
|
Shell
Shell脚本循环控制:shift、continue、break、exit指令
使用这些命令可以让你的Shell脚本像有生命一样动起来。正确使用它们,你的脚本就能像一场精心编排的舞蹈剧目,既有旋律的起伏,也有节奏的跳跃,最终以一场惊艳的表演结束。每一个动作、每一个转折点,都准确、优雅地完成所需要表达的逻辑。如此,你的脚本不只是冰冷的代码,它透过终端的界面,跳着有节奏的舞蹈,走进观众——使用者的心中。
264 60
|
2月前
|
数据采集 监控 Shell
无需Python:Shell脚本如何成为你的自动化爬虫引擎?
Shell脚本利用curl/wget发起请求,结合文本处理工具构建轻量级爬虫,支持并行加速、定时任务、增量抓取及分布式部署。通过随机UA、异常重试等优化提升稳定性,适用于日志监控、价格追踪等场景。相比Python,具备启动快、资源占用低的优势,适合嵌入式或老旧服务器环境,复杂任务可结合Python实现混合编程。
|
4月前
|
Web App开发 缓存 安全
Linux一键清理系统垃圾:释放30GB空间的Shell脚本实战​
这篇博客介绍了一个实用的Linux系统盘清理脚本,主要功能包括: 安全权限检查和旧内核清理,保留当前使用内核 7天以上日志文件清理和系统日志压缩 浏览器缓存(Chrome/Firefox)、APT缓存、临时文件清理 智能清理Snap旧版本和Docker无用数据 提供磁盘空间使用前后对比和大文件查找功能 脚本采用交互式设计确保安全性,适合定期维护开发环境、服务器和个人电脑。文章详细解析了脚本的关键功能代码,并给出了使用建议。完整脚本已开源,用户可根据需求自定义调整清理策略。
537 1
|
6月前
|
Java Linux
自定义linux脚本用于快速jar包启动、停止、重启
自定义linux脚本用于快速jar包启动、停止、重启
323 29
|
6月前
|
存储 Unix Shell
确定Shell脚本在操作系统中的具体位置方法。
这对于掌握Linux的文件系统组织结构和路径方面的理解很有帮助,是我们日常工作和学习中都可能使用到的知识。以上讲解详细清晰,应用简便,是每一个想要精通操作系统的计算机爱好者必备的实用技能。
179 17
|
5月前
|
Java Linux 开发工具
Linux下版本控制器(SVN) -命令行客户端
Linux下版本控制器(SVN) -命令行客户端
162 4