Shell:控制脚本 - 信号量

1. 处理信号

1.1 重温Linux信号

Linux系统和应用程序可以生成超过30个信号。表16-1列出了在Linux编程时会遇到的最常见
的Linux系统信号。
在这里插入图片描述
在这里插入图片描述
通过SIGINT信号,可以中断shell。

你可能也注意到了,shell会将这些信号传给shell脚本程序来处理。而shell脚本的默认行为 是忽略这些信号。它们可能会不利于脚本的运行。要避免这种情况,你可以脚本中加入识别信
号的代码,并执行命令来处理信号。

1.2 生成信号

中断进程

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

$ sleep 100 ^C
$
暂停进程

Ctrl+Z组合键会生成一个SIGTSTP信号,停止shell中运行的任何进程。停止(stopping)进程跟终止(terminating)进程不同:停止进程会让程序继续保留在内存中,并能从上次停止的位置继续运行

当用Ctrl+Z组合键时,shell会通知你进程已经被停止了。

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

方括号中的数字是shell分配的作业号(job number)。shell将shell中运行的每个进程称为作业, 并为每个作业分配唯一的作业号。它会给第一个作业分配作业号1,第二个作业号2,以此类推。

可以用ps命令来查看已停止的作业。

$ sleep 100 ^Z
[1]+ Stopped $
sleep 100
$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 501 2431 2430 0 80 0 - 27118 wait pts/0 00:00:00 bash 
0 T 501 2456 2431 0 80 0 - 25227 signal pts/0 00:00:00 sleep 
0 R 501 2458 2431 0 80 0 - 27034 - pts/0 00:00:00 ps
$

S列中(进程状态),ps命令将已停止作业的状态为显示为T。这说明命令要么被跟踪,要 么被停止了。

如果在有已停止作业存在的情况下,你仍旧想退出shell,只要再输入一遍exit命令就行了。 shell会退出,终止已停止作业。或者,既然你已经知道了已停止作业的PID,就可以用kill命令 来发送一个SIGKILL信号来终止它。

$ kill -9 2456 $
[1]+ Killed			sleep 100
$
捕获信号

trap命令允许你来指定shell 脚本要监看并从shell中拦截的Linux信号。如果脚本收到了trap命令中列出的信号,该信号不再 由shell处理,而是交由本地处理。

trap命令的格式是:

trap commands signals

这里有个简单例子,展示了如何使用trap命令来忽略SIGINT信号,并控制脚本的行为。

$ cat test1.sh
#!/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 10 ]
do
       echo "Loop #$count"
       sleep 1
       count=$[ $count + 1 ]
done
#
echo "This is the end of the test script"
#

捕获这些 信号会阻止用户用bash shell组合键Ctrl+C来停止程序。每次使用Ctrl+C组合键,脚本都会执行trap命令中指定的echo语句,而不是处理该信号并允许shell停止该脚本。

$ ./test1.sh
This is a test script
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
^C Sorry! I have trapped Ctrl-C Loop #6
Loop #7
Loop #8
^C Sorry! I have trapped Ctrl-C Loop #9
Loop #10
This is the end of the test script $

2. 在非控制台下运行脚本

有时你会想在终端会话中启动shell脚本,然后让脚本一直以后台模式运行到结束,即使你退 出了终端会话。这可以用nohup命令来实现。

nohup命令运行了另外一个命令来阻断所有发送给该进程的SIGHUP信号。这会在退出终端会话时阻止进程退出。

nohup命令的格式如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值