《Linux命令行与shell脚本编程大全》 第十五章 学习笔记

本文主要是介绍《Linux命令行与shell脚本编程大全》 第十五章 学习笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第一部分:Linux命令行
《Linux命令行与shell脚本编程大全》 第一章:初识Linux shell
《Linux命令行与shell脚本编程大全》 第二章:走进shell
《Linux命令行与shell脚本编程大全》 第三章:基本的bash shell命令
《Linux命令行与shell脚本编程大全》 第四章:更多的bash shell命令
《Linux命令行与shell脚本编程大全》 第五章:使用Linux环境变量
《Linux命令行与shell脚本编程大全》 第六章:理解Linux文件权限
《Linux命令行与shell脚本编程大全》 第七章:管理文件系统
《Linux命令行与shell脚本编程大全》 第八章:安装软件程序
《Linux命令行与shell脚本编程大全》 第九章:使用编辑器

第二部分:shell脚本编程基础
《Linux命令行与shell脚本编程大全》 第十章:构建基本脚本
《Linux命令行与shell脚本编程大全》 第十一章:使用结构化命令
《Linux命令行与shell脚本编程大全》 第十二章:更多的结构化命令
《Linux命令行与shell脚本编程大全》 第十三章:处理用户输入
《Linux命令行与shell脚本编程大全》 第十四章:呈现数据
《Linux命令行与shell脚本编程大全》 第十五章:控制脚本

第三部分:高级shell编程
《Linux命令行与shell脚本编程大全》 第十六章:创建函数
《Linux命令行与shell脚本编程大全》 第十七章:图形化桌面上的脚本编程
《Linux命令行与shell脚本编程大全》 第十八章:初识sed和gawk
《Linux命令行与shell脚本编程大全》 第十九章:正则表达式
《Linux命令行与shell脚本编程大全》 第二十章:sed进阶
《Linux命令行与shell脚本编程大全》 第二十一章:gawk进阶
《Linux命令行与shell脚本编程大全》 第二十二章:使用其他shell

第四部分:高级shell脚本编程主题
《Linux命令行与shell脚本编程大全》 第二十三章:使用数据库
《Linux命令行与shell脚本编程大全》 第二十四章:使用Web
《Linux命令行与shell脚本编程大全》 第二十五章:使用E-mail
《Linux命令行与shell脚本编程大全》 第二十六章:编写脚本实用工具
《Linux命令行与shell脚本编程大全》 第二十七章:shell脚本编程进阶


第十五章:控制脚本


处理信号

重温Linux信号

信号名称描述
1HUP挂起
2INT中断
3QUIT结束运行
9KILL无条件终止
11SEGV段错误
15TERM尽可能终止
17STOP无条件停止运行,但不终止
18TSTP停止或暂停,但继续在后台运行
19CONT在STOP或TSTP之后恢复执行

默认情况下,bash shell会忽略收到的任何SIGQUIT(3)和SIGTERM(5)信号。

如果bash shell收到了SIGHUP信号,它会退出。但是在退出之前,它会将SIGHUP信号传给shell启动的所有进程(比如shell脚本)。通过SIGINT可以中断shell。Linux内核会停止将CPU的处理时间分配给shell。此时,shell会将SIGINT信号传给shell启动的所有进程。

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

 

产生信号

终止进程

CTRL+C会生成SIGINT信号

暂停进程

CTRL+Z会生成SIGSTP信号

$ gedit a
^Z
[1]+  Stopped                 gedit a

这里看到有一个作业产生,状态为stopped

关于作业讲解可参看(#1)

可以用ps查看已停止的作业,然后用kill将其终止。

捕捉信号

trap commands signal

指定shell脚本观察的信号并拦截

#!/bin/bash
trap "echo you can\'t stop me!" SIGINTcount=1
while [ $count -le 10 ]
doecho "Loop #$count"count=$[ $count + 1]sleep 5
done

执行脚本时候按下CTRL+C,那么此时脚本不会终止,而是打出log

$ signal_test 
Loop #1
^Cyou can't stop me!
Loop #2
^Cyou can't stop me!
……

虽然不能终止它,但是发现,本来应该sleep 5秒的,CTRL+C之后,这次sleep就马上结束了

捕捉脚本的退出

同上面一样,只需把trap捕捉的信号改为EXIT即可

trap "echo bye!" EXIT

当脚本退出的时候则会输出:

$ signal_test 
Loop #1
^Cbye!

移出捕捉

trap - signals

在连词线后面加信号即可。

 

以后台模式运行脚本

后台运行脚本

只需在命令后加&即可

此时会输出作业ID和进程ID

$ gedit signal_test &
[1] 9651

运行多个后台作业

$ gedit redirect_test &
[2] 9689
[1]   Done                    gedit signal_test
$ signal_test &
[3] 9699

通过ps au可以看到程序执行情况

1000      9689  2.5  0.4 395676 29944 pts/0    Sl   20:12   0:00 gedit redirect_test

1000      9699  0.0  0.0  13624  1468 pts/0    S    20:12   0:00 /bin/bash ./signal_test

退出终端

通过ps的输出,可以看到每个后台进程都绑定到了该终端会话的终端上了(pts/0).如果进程会话退出了,后台进程也会退出。

退出终端时,如果有关联到终端的还在运行的后台进程,有的终端模拟器会提醒你,但不是全部。

在非控制台下运行脚本

nohup命令可以帮助你使得脚本一直在后台运行,直到其完成,即使退出了终端会话。

nohup command args...

$ nohup gedit signal_test &
[1] 9878
$ nohup: ignoring input and appending output to `nohup.out'

如果关闭该会话,脚本会忽略任何终端发过来的SIGHUP信号

由于nohup命令会从终端解除进程的关联,进程会丢掉到STDOUT和STDERR的链接。

为了保存输出,nohup会自动将STDOUT和STDERR重定向到名为nohup.out的文件中

注意:如果使用nohup执行了多个命令,那么这些输出都会重定向到nohup.out中!

 

作业控制

启动、停止、无条件终止以及恢复作业的这些功能统称为作业控制。

查看作业

jobs可以列出分配给shell的作业

-l:列出进程的PID以及作业号

-n:只列出上次shell发出的通知后改变了状态的作业

-p:只列出作业的PID

-r:只列出运行中的作业

-s:只列出已停止的作业

$ gedit test.xml &
[1] 5463
$ jobs
[1]+  Running                 gedit test.xml &

带加号的作业会被当成默认的作业。使用作业命令时,如果未指定作业号,那么该作业会被当做操作对象。

带减号的作业会在当前默认作业处理完毕的时候成为下一个默认作业。

任何时候都不会有超过1个的带加号的作业和带减号的作业

$ signal_test 
Loop #1
^Z
[1]+  Stopped                 signal_test
$ signal_test 
Loop #1
^Z
[2]+  Stopped                 signal_test
$ signal_test 
Loop #1
^Z
[3]+  Stopped                 signal_test
$ jobs -l
[1]   5596 Stopped                 signal_test
[2]-  5598 Stopped                 signal_test
[3]+  5602 Stopped                 signal_test
$ kill -9 5602
$ jobs -l
[1]-  5596 Stopped                 signal_test
[2]+  5598 Stopped                 signal_test

kill了3号任务之后,之前带减号的2号任务就变成了当前的任务

重启停止的作业

bg jobid:在后台重启任务

fg jobid:在前台重启任务

(fg、bg更多讲解可参看(#1))

调整谦让度

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

nice命令

nice -n level command

普通用户无法设置更高优先级,会得到如下错误

$ nice -n -1 gedit 
nice: cannot set niceness: Permission denied

renice命令

renice level -p pid

使用renice时需要注意:

1.只能对属于你的进程执行

2.只能降低优先级

3.root用户可以随意调整任何进程任何优先级

 

定时运行作业

atd守护进程会检查系统上的一个特殊目录(通常为/var/spool/at。我机器上面没有这个目录,在我机器上应该是/var/spool/cron/atjobs)

默认情况下,atd守护进程会每60s检查一下这个目录。有作业时,atd守护进程会检查作业设置运行的时间。

at命令的格式

at [-f filetime

默认情况下,at会将STDIN的输入放到队列中。-f可以指定执行的脚本文件。

下面是at可以识别的时间格式:

标准小时和分钟,比如10:11

~AM/~PM指示符,比如10:32~PM

特定可命名的时间:比如now、noon、midnight、teatime(4~PM)

如果指定的时间已经过去了,那么at会在第二天这个时候执行

 

标准日期格式:比如MMDDYY、MM/DD/YY、DD.MM.YY

文本日期,比如Jul 4,有无年份均可

 

也可指定时间增量

当前时间+25min

明天11:32~PM

11:50+4天

使用at命令,作业会被提交到作业队列(job queue)中。有26种不同优先级的队列,用小写a-z表示。

作业队列字母排序越高,优先级就越低。可以使用-q执行优先级。

$ at -f for_test noon
warning: commands will be executed using /bin/sh
job 8 at Thu Aug 29 12:00:00 2013
$ sudo ls /var/spool/cron/atjobs/
a00008015e6130
$ at -q c -f for_test noon
warning: commands will be executed using /bin/sh
job 9 at Thu Aug 29 12:00:00 2013
$ sudo ls /var/spool/cron/atjobs/
a00008015e6130	c00009015e6130

当任务执行完毕的时候,/var/spool/cron/atjobs/下的文件会被删除

注意:

使用at的时候,我们会发现有这样一行log输出

warning: commands will be executed using /bin/sh

也就是说,系统会用/bin/sh来执行脚本,而不是使用bash!

这样就会遇到一些问题,足以让人崩溃。

大多数:inux发行版中,赋给/bin/sh的默认shell是bash shell,但是Ubuntu将dash shell作为其默认shell。

为了使用bash执行脚本,我们需要做个wrapper

bash /home/su1216/android/source/linux_learned/for_test

保存为文件,我这里命名它为bash_wrapper

然后用at执行此脚本即可

$ at -f bash_wrapper now
warning: commands will be executed using /bin/sh
job 27 at Thu Aug 29 16:08:00 2013

这个时候,世界将恢复正常。

获取作业的输出

作业运行时,屏幕不会有输出。系统会将提交作业的用户Email作为STDOUT和STDERR。

在机器上要安装mailutils

之后执行mail,可能会出现下面的问题:

$ mail
Cannot open mailbox /var/mail/su1216: Permission denied
No mail for su1216

可以按着下列步骤解决:

sudo touch /var/mail/$USER
sudo chown $USER:mail /var/mail/$USER
sudo chmod o-r /var/mail/$USER
sudo chmod g+rw /var/mail/$USER

上面的命令之前都已经讲过,意义分别为

创建/var/mail/$USER文件

改变属主

去除其他用户的读权限

给属组增加读写权限

列出等待的作业

atq可以列出等待的作业

$ atq
30	Fri Aug 30 16:28:00 2013 a su1216

删除作业

atrm job

注意:只能删除自己提交的作业

计划定期执行脚本

Linux系统使用cron来定期执行作业。cron会在后台运行并检查称作cron时间表(cron table)来获得计划执行的作业。

cron时间表

cron时间表格式如下:

min hour dayofmonth month dayofweek command

cron时间表允许使用特定的值、范围、通配符指定时间。比如:

15 10 * * * command

dayofmonth、month和dayofweek字段中使用通配符,表示字段值的可以取到的全集。上面表示在每天的10:15都要执行command

可以使用三字符文本值(mon、tue……)或者数值(0=周日,6=周六)指定dayofweek

注意:如何指定每月的最后一天

可以使用date来查看明天的日期是不是01

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

在每天上午12点的时候检查明天是不是01

cron时间表必须指定命令的全路径。可以添加任何参数和重定向符号

 

cron程序是假定Linux是7*24小时运行的!

如果脚本还没有执行,系统就关闭了,过了执行时间再开启机器,那么cron是不会执行过期的脚本的。

构建cron时间表

每个用户都有自己的cron时间表

crontab -l:列出当前用户的cron时间表,默认cron时间表是不存在的。可以使用-e参数来添加条目。

cron目录

当不要求有精确的时间执行脚本时,用预配置的cron脚本目录会更方便。

有4个基本目录

$ ls /etc/cron.*ly
/etc/cron.daily:
0anacron  apport  apt  bsdmainutils  dpkg  exim4-base  logrotate  man-db  mlocate  popularity-contest  quota  samba  standard/etc/cron.hourly:/etc/cron.monthly:
0anacron/etc/cron.weekly:
0anacron  apt-xapian-index  cvs  man-db

每天执行一次,则只需把脚本拷贝到 /etc/cron.daily下面即可。

anacron程序

anacron和cron不同,他会处理因为关机而过期的任务。

anacron只会处理cron目录的程序。它用时间戳来决定作业是否在适当的计划间隔内运行了。每个cron目录都有时间戳文件,位于/var/spool/anacron

anacron程序有自己的用来检查作业目录的表,通常位于/etc/anacrontab

anacron时间表于cron时间表格式不同,具体如下:

period delay identifier command

period单位为天,delay系统启动多少分钟后,anacron开始执行错过的脚本。command包括run-parts程序和一个cron脚本目录。run-parts程序负责运行目录中传给它的任何脚本。

注意:anacron不会运行位于/etc/cron.hourly的脚本

identifier是一个特殊的非空白字符串,它用于唯一识别日志消息和错误Email中的作业。

下面是我机器上面的anacrontab

$ cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron# See anacron(8) and anacrontab(5) for details.SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin# These replace cron's entries
1	5	cron.daily	 nice run-parts --report /etc/cron.daily
7	10	cron.weekly	 nice run-parts --report /etc/cron.weekly
@monthly	15	cron.monthly nice run-parts --report /etc/cron.monthly

 

启动时运行

开机时运行脚本

开机过程

开始运行Linux系统时,Linux内核会加载到内存中并运行。它做的第一件事是开始UNIX System V过程或Upstart init过程(具体取决于发行版和版本)。然后这个过程将负责启动Linux系统上所有其他进程。

System V init过程

System V init过程会读取/etc/inittab文件。inittab文件会列出系统的运行级(run level)

基于Red Hat发行版的Linux运行级别

运行级别描述
0关机
1单用户模式
2多用户模式,通常不支持网络
3全功能多用户模式,支持网络
4可定义用户
5多用户模式,支持网络和图形化X Window会话
6重启

基于Debian发行版的Linux运行级别(包括Ubuntu、Linux Mint等)

运行级别描述
0关机
1单用户模式
2-5多用户模式,支持网络和图形化X Window会话
6重启

Ubuntu没有/etc/inittab文件,默认情况下会以运行级别2启动系统,想要修改,需要自行创建/etc/inittab文件

有些Linux发行版将开机脚本放在/etc/rc#.d,其中#代表运行级别。有些放在/etc/init.d,有些放在/etc/init.d/rc.d下面

Upstart init过程

Upstart不关注系统运行级别,而关注时间。

在Upstart中,系统开机称为开机事件(startup event)。

Upstart使用位于/etc/event.d或/etc/init目录下的文件来启动进程,具体取决于发行版和版本。

为了向后兼容,许多Upstart实现仍会调用较早的位于/etc/init.d以及/etc/rc#.d目录中的System V init脚本

定义自己的开机脚本

Linux本地开机文件位置

发行版文件位置
debian/etc/init.d/rc.local
Fedora/etc/rc.d/rc.local
Mandriva/etc/rc.local
OpenSure/etc/init.d/boot.local
Ubuntu/etc/rc.local

可以修改本地开机文件,使用脚本时,必须指定脚本的全路径。

警告:不同Linux发行版在开机过程的不同事件执行该本地开机脚本。有时该脚本会在网络支持等启动前运行。

在新shell中启动

bash shell会用主目录下的两个文件.bash_profile和.bashrc来自动启动脚本并设置环境变量

当新shell是新的登录生成的话,bash shell会运行.bash_profile文件。可以把任何登录时要运行的脚本放到该文件中。

当新shell启动时,包括有新的登录的情况,bash shell 会运行.bashrc文件。

如果想为系统中所有用户运行一个脚本。大多数Linux发行版提供了/etc/bashrc文件

更多登录shell和非登录shell内容参见(#2)



1.《Unix & Linux 大学教程》 - 第二十六章 进程和作业控制

2.《Unix & Linux 大学教程》 - 第十四章:使用shell:初始化文件



转贴请保留以下链接

本人blog地址

http://su1216.iteye.com/

http://blog.csdn.net/su1216/

这篇关于《Linux命令行与shell脚本编程大全》 第十五章 学习笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/694472

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss