SHELL脚本学习(七) 脚本控制

一、处理信号

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

1.1 linux信号

linux系统和应用程序可以产生超过30个信号。下面列出最常见的linux系统信号:

信 号描 述
1SIGHUP挂起(hang up)进程
2SIGINT中断(interrupt)进程
3SIGQUIT停止(stop)进程
9SIGKILL无条件终止(terminate)进程
15SIGTERM尽可能终止进程
18SIGCONT继续运行停止的进程
19SIGSTOP无条件停止,但不终止进程
20SIGTSTP停止或暂停(pause),但不终止进程

默认情况下,bash shell会忽略SIGQUIT和SIGTERM信号。但是bash shell会处理收到的所有SIGHUP和SIGINT信号。

1.2 产生信号

bash shell 允许使用键盘组合键生成两种基本的linux信号。这个特性在需要停止或暂停失控脚本时非常方便。

1.2.1 中断进程

Ctrl+C 组合键生成SIGINT信号。

$ sleep 60
^C
$ 
1.2.2 暂停进程

Ctrl+Z 组合键生成SIGHUP信号

$ sleep 60
^Z
[1]+  Stopped                 sleep 60

方括号中的数字是作业号。shell将运行的各个进程称为作业,并为其分配在当前shell内唯一的作业号。
作业号从1开始,然后是2,依次递增。

$ ps -l
F S   UID     PID    PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000   18307 4192051  0  80   0 -  2170 do_wai pts/15   00:00:00 bash
0 T  1000  208634   18307  0  80   0 -  1369 do_sig pts/15   00:00:00 sleep
0 R  1000  208849   18307  0  80   0 -  2202 -      pts/15   00:00:00 ps

第2行第2列 T 表示sleep命令已暂停。

1.2.3 终止进程

可以使用kill命令向进程发送SIGKILL(9)信号

kill -9 pid
pid 可以通过ps命令查看

1.3 捕获信号

trap命令可以指定shell脚本需要侦测并处理的linux信号。如果脚本收到了trap命令中列出的信号,
则该信号不在由shell处理,而是由本地处理。

trap command signals

#!/usr/bin/bash
trap "echo I have trap Ctrl+C" SIGINT

echo this is a test script

count=1

while [ $count -le 10 ]
do
    echo "loop #$count"
    sleep 1
    count=$[ $count+1 ]
done

#在bash shell中执行脚本
$ ./test.sh
this is a test script
loop #1
loop #2
loop #3
^CI have trap Ctrl+C
loop #4
loop #5
loop #6
^CI have trap Ctrl+C
loop #7
loop #8
loop #9
loop #10
1.4 获取脚本退出

除了在shell脚本中捕获信号,也可以在shell脚本退出时捕获信号。
这是在shell完成任务时执行命令的一种简便方法。

#!/usr/bin/bash
trap "echo bye bye" EXIT
echo this is a test script

count=1
while [ $count -le 5 ]
do
    echo "loop #$count"
    sleep 1
    count=$[ $count+1 ]
done

#在bash shell中执行脚本
$ ./test.sh
this is a test script
loop #1
loop #2
loop #3
loop #4
loop #5
bye bye
1.5 修改信号

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

#!/usr/bin/bash
trap "echo old trap command" SIGINT

echo this is a test script

count=1

while [ $count -le 3 ]
do
    echo "loop #$count"
    sleep 1
    count=$[ $count+1 ]
done

trap "echo new trap command" SIGINT
count=1
while [ $count -le 3 ]
do
    echo "loop #$count"
    sleep 1
    count=$[ $count+1 ]
done
#在bash shell中执行脚本
$ ./test.sh
this is a test script
loop #1
loop #2
^Cold trap command
loop #3
loop #1
^Cnew trap command
loop #2
loop #3
1.6 移除信号

想要移除信号,在trap命令与希望恢复默认行为的信号列表之间加上连字符(–)即可。

trap – signals

二、以后台模式运行脚本

2.1 后台运行脚本

以后台运行脚本非常简单,只需在脚本名后面加上 & 即可。

脚本名 &

$ ./test.sh &
[1] 229686

方括号内是作业号,后面跟的是PID。

三、在非控制台下运行脚本

有时候即便是退出了终端会话,也想在终端会话中启动shell脚本,让脚本一直以后台模式运行到结束。
这个是使用nohup命令实现的。
nohup命令能阻断发给特定进程的SIGHUP信号。当退出终端会话时,可以避免进程退出。

nohup命令格式:

nohup command

$ nohup ./test.sh &
[1] 233484
nohup: ignoring input and appending output to 'nohup.out'

由于nohup命令会解除终端和进程的关联,因此不再同STDOUT和STDERR绑定在一起。
为了保存该命令产生的输出,nohup命令会自动将STDOUT和STDERR产生的消息重定向到
一个名为 nohup.out 的文件中

nohup.out 文件一般会在当前工作目录创建,否则会在$HOME目录中创建

四、作业控制

4.1 查看作业

jobs命令允许用户查看shell正在处理的作业:

jobs
[1]+  Done                    nohup ./test.sh
选 项描 述
-l列出进程的PID及作业号
-n只列出上次shell发出通知后状态发生状态的作业
-p只列出作业的PID
-r只列出运行中的作业
-s只列出已停止的作业
4.2 重启已停止的作业

在bash 作业控制中,可以将已停止的作业作为后台或前台进程重启。

bg 作业号 #以后台模式重启作业

fg 作业号 #以前台模式重启作业

  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值