shell脚本控制

news2024/12/22 19:15:54

shell脚本编程系列


处理信号

Linux利用信号与系统中的进程进行通信,通过对脚本进行编程,使其在收到特定信号时执行某些命令,从而控制shell脚本的操作。

  • Linux信号
    shell脚本编程会遇到的最常见的Linux系统信号如下表所示:
    在这里插入图片描述

在默认情况下,bash shell会忽略收到的任何SIGQUIT(3)信号和SIGTERM(15)信号(因此交互式shell才不会被意外终止)。
bash shell会处理接收到的所有SIGHUP(1)和SIGINT(2)信号。
如果收到SIGHUP信号,比如离开交互式shell时,bash shell就会退出,但是在退出之前,它会将SIGHUP信号传给所有由该shell启动的进程,包括正在运行的脚本。
如果收到SIGINT信号,shell会被中断,Linux内核将不再为shell分配CPU处理时间。当出现这种情况时,shell会将SIGINT信号传给由其启动的所有进程。
shell脚本默认行为时忽略Linux信号,因为不利于脚本运行,要避免这种情况,可以在脚本中加入识别信号的代码,并做相应的处理。

  • 产生信号
    中断进程 CTRL+C组合键会生成SIGINT信号
    在这里插入图片描述

暂停进程 Ctrl+Z组合键会生成SIGTSTP信号,停止shell中运行的任何进程。停止进程和终止进程不同,前者让程序驻留在内存中,还能从上次停止的位置继续运行。
在这里插入图片描述

  • 捕获信号
    trap commands signals
    trap命令可以指定shell脚本需要侦测并拦截的Linux信号。在commands部分列出想要shell执行的命令,在signals部分列出要捕获的信号(多个信号之间以空格分隔),指定信号时,可以使用信号的值或信号名
    #!/bin/bash
    #Testing signal trapping
    #
    trap "echo ' Sorry! I have trapped Ctrl-C'" SIGINT
    #
    echo This is a test script.
    #
    count=1
    while [ $count -le 5 ]
    do
         echo "Loop #$count"
         sleep 1
         count=$[ $count + 1 ]
    done
    #
    echo "This is the end of test script."
    exit
    
    trap "" SIGINT允许脚本完全忽略SIGINT信号,继续执行重要的工作
  • 捕获脚本退出
    除了在shell脚本中捕获信号,也可以在脚本退出是捕获信号,这也是shell完成任务时执行命令的一种简便方法。要捕获脚本退出,只需要在trap命令后加上EXIT信号即可
    #!/bin/bash
    #Testing exit trapping
    #
    trap "echo Goodbye..." EXIT
    #
    count=1
    while [ $count -le 5 ]
    do
         echo "Loop #$count"
         sleep 1
         count=$[ $count + 1 ]
    done
    #
    exit
    
  • 修改或移除信号捕获
    重新使用带有新内容的trap命令可以修改信号捕获
    在trap命令与希望恢复默认行为的信号之间加上两个连字符可以移除设置好的信号捕获
    trap -- SIGINT
    #!/bin/bash
    #Removing a set trap
    #
    trap "echo ' Sorry...Ctrl-C is trapped.'" SIGINT
    #
    count=1
    while [ $count -le 3 ]
    do
         echo "Loop #$count"
         sleep 1
         count=$[ $count + 1 ]
    done
    #
    trap -- SIGINT
    echo "The trap is now removed."
    #
    count=1
    while [ $count -le 3 ]
    do
         echo "Second Loop #$count"
         sleep 1
         count=$[ $count + 1 ]
    done
    #
    exit
    

以后台模式运行脚本

以后台模式执行脚本,只需要在脚本名后面加上&即可,比如 ./backgroundscript.sh &,&符号会将脚本与当前shell分离开来,并将脚本作为一个独立的后台进程运行
在指定之后,会在控制台输出类似于[1] 2595的字样,其中方括号中的1是shell分配给后台进程的作业号,而后面的2595是Linux系统为进程分配的进程ID(PID)。Linux系统中的每个进程都必须有唯一的PID
当后台进程运行时,它仍然会使用终端显示器来显示STDOUT和STDERR信号

#!/bin/bash
#Test running in the background
#
echo "Starting the script..."
count=1
while [ $count -le 5 ]
do
     echo "Loop #$count"
     sleep 1
     count=$[ $count + 1 ]
done
#
echo "Script is completed."
exit

每次启动新作业时,Linux系统都会为其分配新的作业号和PID。在终端会话中使用后台进程一定要小心,每一个后台进程都和终端会话(pts/0)关联在一起,如果终端会话退出,那么后台进程也会随之退出。

在非控制台下运行脚本

nohup命令能阻断发给特定进程的SIGHUP信号,这样当终端会话退出时,就可以避免进程退出,格式为nohup command
由于nohup命令会将进程与终端的关联解除,所以进程不再同STDOUT和STDERR绑定在一起,默认情况下,nohup命令会将二者产生的消息重定向到一个名为nohup.out的文件中
nohup ./testAscript.sh &
在这里插入图片描述

如果使用nohup命令运行了另一个命令,则输出会追加到已有的nohup.out文件中。当运行同一目录中的多个命令时,一定要当心,因为所有的命令输出都会发送到同一个nohup.out文件中

作业控制

作业控制包括启动、停止、杀死和恢复作业
通过jobs命令查看作业
其中-l选项会列出进程的PID以及作业号
-n 只列出上次shell发出通知后状态发生改变的作业
-r 只列出运行中的作业
-s 只列出已停止的作业
在这里插入图片描述

删除已停止的作业,只需要使用kill命令向其pid发送SIGKILL(9)信号即可
要以后台模式重启作业,可以使用bg命令
在这里插入图片描述

如果存在多个作业,则需要在bg命令后加上作业号,以便于控制
在这里插入图片描述

要以前台模式重启作业,可以使用带有作业号的fg命令,比如fg 2

调整谦让度

在多任务操作系统中,内核负责为每个运行的进程分配CPU时间。调度优先级也称为谦让度(nice value),是指内核为进程分配的CPU时间(相对于其他进程)。在Linux系统中,由shell启动的所有进程的调度优先级默认都是相同的
调度优先级是一个整数值,取值范围从-20(最高优先级)到+19(最低优先级)。默认情况下, bash shell以优先级0来启动所有进程
nice命令允许在启动命令时设置调度优先级,通过选项-n指定即可

nice -n 10 ./jobcontrol.sh > jobcontrol.out &

在这里插入图片描述

只有root用户或这特权用户才能提高作业的优先级
使用renice命令可以修改系统中已运行命令的优先级
在这里插入图片描述

定时运行作业

使用at命令可以调度作业,对于定期运行的脚本不方便,而Linux系统使用cron程序调度需要定期执行的作业。
cron在后台运行,会检查一个特殊的cron时间表,从中获取已安排执行的作业

每天的10:15运行一个命令,cron表达式为:15 10 * * * command
每周一的下午4:15执行的命令 15 16 * * 1 command
每月第一天的12点执行命令 00 12 1 * * command

crontab -l 可以列出已有的时间表
在这里插入图片描述

crontab -e会进入一个文件编辑器,添加任务
在这里插入图片描述

如果要执行的脚本精确度要求不高,可以用预设置的cron脚本目录即可,预配置的基础目录共有4个:hourly、daily、monthly和weekly
ls /etc/cron.*ly
在这里插入图片描述

如果你的脚本需要每天执行一次,那么将脚本复制到daily目录,cron就会每天执行它

使用新shell启动脚本

用户登录shell的时候会执行一些启动文件,比如.bash_profile、.bashrc.
在主目录下的.bashrc文件中加入一条简单的echo语句,那么每次启动一个新的shell时都会执行这个语句.
在这里插入图片描述

总结

Linux系统允许使用信号来控制shell脚本。bash shell可以接收信号并将其传给由shell进程生成的所有进程。Linux信号可以轻而易举地杀死失控的进程或暂停耗时的进程。
可以在脚本中用trap命令捕获信号并执行特定命令。这个功能提供了一种简单的方法来控制脚本运行时用户能够将其中断。
在默认情况下,当在终端会话shell中运行脚本时,交互式shell会被挂起,直到脚本运行完毕。你可以在命令后加上一个&符号使脚本或命令以后台模式运行。当在后台模式运行命令或脚本时,交互式shell会被返回,允许你继续输入其他命令。
通过这种方法运行的后台进程仍与终端会话绑定。如果退出终端会话,那么后台进程也会随之退出。nohup命令可以租着这种情况发生。该命令可以拦截任何会导致命令停止运行的信号(比如退出终端会话的信号)。如此一来,即便已经退出了终端会话,脚本也能继续在后台执行。
当将进程置入后台时,仍然可以对其施加控制。jobs命令可以查看shell会话启动的进程。只要知道了后台进程的作业号,就能用kill命令向该进程发送信号,或者用fg命令将该进程带回shell会话的前台。你可以用ctrl+z组合键挂起正在运行的前台进程,也可以用bg命令将其置于后台模式。
nice命令和renice命令可以调整进程的优先级。通过降低进程的优先级,可以使其他高优先级进程获得更多的CPU时间。当运行消耗大量CPU时间的长期进程时,这项特性特别方便。
除了控制处于运行状态的进程,还可以决定何时启动进程。无须直接在命令行界面运行脚本。可以将进程安排在指定时间运行,实现方法不止一种,at命令允许在预设的时间运行脚本,cron程序提供了定时运行脚本的接口,anacron可以确保及时运行脚本(服务器关闭过程中的任务在启动之后会执行)。
最后,Linux系统提供了一些脚本文件,可以让脚本在启动新的bash shell时运行,与此类似,位于用户主目录的启动文件提供了一个位置,以存放新shell启动时需要运行的脚本和命令。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/449756.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ros】6.ros激光雷达SLAM(建图定位)

百行业为先 ,万恶懒为首。——梁启超 文章目录 :smirk:1. 激光SLAM:blush:2. 二维激光SLAM:satisfied:3. 三维激光SLAM 😏1. 激光SLAM SLAM(同步定位与地图构建)是一种机器人感知技术,用于在未知环境中同时确定机器人…

java调用webservicer的方法

对于使用 Webservicer的方式,一般采用 Java API调用的方式。Webservicer是一个运行在浏览器中的客户端程序,它可以通过 Webservicer的接口来访问服务器上的服务。 使用 Java调用 Webservicer有两种方式: 下面是一个简单的例子: 2、…

零基础,零成本,部署一个属于你的大模型

前言 看了那么多chatGPT的文章,作为一名不精通算法的开发,也对大模型心痒痒。但想要部署自己的大模型,且不说没有算法相关的经验了,光是大模型占用的算力资源,手头的个人电脑其实也很难独立部署。就算使用算法压缩后的…

数据结构和算法学习记录——小习题-二叉树的遍历二叉搜索树

目录 二叉树的遍历 1-1 1-2 1-3 二叉搜索树 2-1 2-2 2-3 2-4 答案区 二叉树的遍历 1-1 假定只有四个结点A、B、C、D的二叉树,其前序遍历序列为ABCD,则下面哪个序列是不可能的中序遍历序列? .ABCD .ACDB .DCBA .DABC 1-2 对于…

最精简:windows环境安装tensorflow-gpu-2.10.1

Tensorflow 2.10是最后一个在本地windows上支持GPU的版本 1. 通过.whl文件方式安装2.创建anaconda虚拟环境3.安装对应的cuda与cudnn版本,local不必装cuda和cudnn4. 测试tensorflow gpu是否可用 1. 通过.whl文件方式安装 .whl文件的下载地址: tensorflow…

windows下使用vite创建vue项目

windows下使用vite创建vue项目 1 下载安装配置NodeJS1.1 下载1.2 安装1.3 配置1.4 npm镜像加速配置1.6 设置环境变量 2 Vite简单介绍3 Vite创建vue项目3.1 vite创建vue项目的命令3.2 vite创建vue项目步骤 1 下载安装配置NodeJS 1.1 下载 下载地址:https://nodejs.…

全注解下的SpringIoc 续2-bean的生命周期

spring中bean的生命周期 上一个小节梳理了一下Spring Boot的依赖注入的基本知识,今天来梳理一下spring中bean的生命周期。 下面,让我们一起看看bean在IOC容器中是怎么被创建和销毁的。 bean的生命周期大致分为四个部分: #mermaid-svg-GFXNEU…

数据分类分级 数据识别-识别日期类型数据

前面针对数据安全-数据分类分级方案设计做了分析讲解,具体内容可点击数据安全-数据分类分级方案设计,不再做赘述 上面图片是AI创作生成!如需咒语可私戳哦! 目录 前言需求日期格式代码日期类型数据对应正则表达式前言 要做数据分类分级,重要的是分类分级模版的合理性和数…

一致性 Hash 算法 及Java TreeMap 实现

1、一致性 Hash 算法原理 一致性 Hash 算法通过构建环状的 Hash 空间替线性 Hash 空间的方法解决了这个问题,整个 Hash 空间被构建成一个首位相接的环。 其具体的构造过程为: 先构造一个长度为 2^32 的一致性 Hash 环计算每个缓存服务器的 Hash 值&…

「C/C++」C++对已有的类进行扩充

博客主页:何曾参静谧的博客 文章专栏:「C/C」C/C学习 目录 相关术语一、 继承二、组合 相关术语 继承:继承父类后可以拥有父类对应的属性和方法。 组合:将类作为成员对象,基类可以直接调用派生类对应的属性和方法。 一…

MySQL_第08章_聚合函数

第08章_聚合函数 讲师:尚硅谷 - 宋红康(江湖人称:康师傅) 官网: http://www.atguigu.com 我们上一章讲到了 SQL 单行函数。实际上 SQL 函数还有一类,叫做聚合(或聚集、分组)函…

59 openEuler 22.03-LTS 搭建MySQL数据库服务器-软件介绍和配置环境

文章目录 59 openEuler 22.03-LTS 搭建MySQL数据库服务器-软件介绍和配置环境59.1 软件介绍59.2 配置环境59.2.1 关闭防火墙并取消开机自启动59.2.2 修改SELINUX为disabled59.2.3 创建组和用户59.2.4 创建数据盘59.2.4.1 方法一:在root权限下使用fdisk进行磁盘管理5…

JVM笔记 —— 垃圾回收(GC)详解

一、垃圾回收的分类 针对HotSpot JVM的实现,它里面的GC其实准确分类只有两大种: Partial GC:部分收集模式 Young GC:只收集年轻代的GCOld GC:只收集老年代的GC。只有CMS中有这个模式。Mixed GC:收集整个年轻代以及部分…

mybatis的基本使用和理解

mybatis的基本使用和理解 Lombok的使用(使用注解的方式将实体类中的get、set、构造函数代替) Lombok是一个Java库,能自动插入编辑器并且构建工具,简化Java开发。通过添加注解的方式,不需要为类编写getter或equals方法&#xff0…

Vue3 + TS4.8踩坑之配置husky问题env: sh\r: No such file or directory

一、基本情况: 硬件环境:MacOS 10.14.6 背景:用vue3官方npm init vuelatest初始化创建的vue3 ts4.8项目。 二、问题和解决方案: 问题1:git commit的时候提示:env: sh\r: No such file or directory 原…

0121 进程管理

1.在Linux中,每个执行的程序都称为一个进程。每一个进程都分配一个ID号(pid进程号) 2.每个进程都可能以两种方式存在,前台和后台。前台进程即用户当前屏幕上可进行的操作,后台进程即实际操作,由于屏幕上无…

Java中源文件声明规则,以及java包,import关键字的使用

Java中源文件声明规则,以及java包,import关键字的使用。 1. 源文件声明规则 当在一个源文件中定义多个类,并且还有import语句和package语句时,要特别注意以下规则: a. 一个源文件中只能有一个 public 类。 b. 一个源…

LC电路是如何产生振荡的

电容和电感是两个储能元件,当电源给电容充电完成后, 将开关切到电感,电电感两端的电压是一个正弦波,正弦波频率是: 这时我们称电感和电容产生了振荡。 当然由于电感和电容都是有损耗的,所以这种振荡会慢慢的衰减&…

【文献查找使用】

目录 知识框架No.1 中文文献一、查找、二、下载、三、引用、页码四、什么是DOI呢??? No.2 外文文献一、查找二、下载三、引用、页码 No.3 如何在不下载的情况下进行正确引用呢??一、谷歌学术进行查询二、上sci-hub网站…

使用python的cartopy库读取shapefile文件 .shp文件是乱码

文章目录 问题解决方法 问题 使用python的cartopy库读取shapefile文件即.shp文件乱码 我在使用python的cartopy库读取shapefile文件时出现了乱码 record的.attributes的[‘name’]都是乱码 from cartopy.io import shapereader shp_pathr/home/mw/project/北京市1.shp#文件路…