# 信号

Linux 利用信号与运行在系统中的进程进行通信,常见的 Linux 系统信号:

  • 1-- SIGHUP -- 挂起进程
  • 2-- SIGINT -- 终止进程
  • 3-- SIGQUIT -- 停止进程
  • 9-- SIGLIKILL -- 无条件终止进程
  • 15-- SIHTERM -- 尽可能终止进程
  • 17-- SIGSTOP -- 无条件停止进程,但不是终止
  • 18-- SIGTSTP -- 停止或暂停进程,但不是终止
  • 19-- SIGCONT -- 继续运行停止的进程

crtl+c 会生成 SIGINT 信号,停止 shell 当前运行的所有进程。
ctrl+z 会生成 SIGTSTP 信号,停止 shell 中运行的任何进程。

cyan@cyan-virtual-machine:~$ sleep 1000
^Z
[1]+  Stopped                 sleep 1000
cyan@cyan-virtual-machine:~$ ps -l
F S   UID     PID    PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000   30447   30445  0  80   0 -  3559 do_wai pts/0    00:00:00 bash
0 T  1000   33293   30447  0  80   0 -  2789 do_sig pts/0    00:00:00 sleep
0 R  1000   33294   30447  0  80   0 -  3623 -      pts/0    00:00:00 ps

S 列中, T 标志就是进程被暂停。使用 ps 获得希望杀死的进程的 PID ,使用 kill -9 PID

# trap 命令

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

其使用格式为: trap commands signals

#!/bin/bash
trap "echo 'I have trapped ctrl-c'" SIGINT
sleep 1000

在睡眠期间使用 ctrl+c 就会打印这句话。

在很多程序中,想要实现程序正常运行结束或者外部发送信号退出,都会打印 Goodby... ,可以加上这句话

trap "echo 'Goodby...'" Exit

trap 可以修改或是移除,其重点就是先到先占位,比如第一行设置了 trap 指令,在第 20 行修改或移除了该信号,那么第一行 trap 的只会在 1~19 行生效。

# 删除,单(双)短横线都可以
trap --SIGINT

# 后台模式

最开始就提到过,在运行脚本时加上 & ,就能将进程置入后台。后台模式中,进程不会和终端会话上的 STDINSTDOUTSTDERR 关联 。

# 最后

shell 脚本的基本编程到此为止,之后我们会进入高级 shell 脚本编程,其中会涉及到函数,著名的流编辑器 sedgawk ,以及正则表达式四个主要部分。然后就可以结束此次 Linuxshell 编程的学习了。