shell向子进程发送信号

处理包含子进程的脚本,假设您希望终止任意子进程,那么还需要停止这些脚本。trap 命令完成此操作。

子进程

& 运行的子进程,最为后台程序运行,父进程与子进程之间为异步

已直接方式运行子进程,此时子进程在前台运行,父进程与子进程之间为同步

sleep 10   #等待10秒,再继续下一操作
sleep 10 & #当前shell不等待,后台子shell等待

trap

Unix system by design doesn’t allow any script/program to trap SIGKILL due to security reasons.

Setting a trap for SIGKILL or SIGSTOP produces undefined results.

trap 捕捉到信号之后三种处理方式

  1. 执行一段代码来处理信号 trap "commands" signal-list or trap 'commands' signal-list
  2. 接受信号的默认操作,即恢复信号默认操作 trap signal-list
  3. 忽视信号 trap "" signal-list

注意事项:

  1. SIGKILL SIGSTOP SIGSEGV SIGCONT不设置捕捉
  2. 在捕捉到signal-list中指定的信号并执行完相应的命令之后, 如果这些命令没有将shell程序终止的话,shell程序将继续执行收到信号时所执行的命令后面的命令,这样将很容易导致shell程序无法终止。
  3. 在trap语句中,单引号和双引号是不同的,当shell程序第一次碰到trap语句时,将把commands中的命令扫描一遍。此时若commands是用单引号括起来的话,那么shell不会对commands中的变量和命令进行替换

Example

全部使用同步方式

#!/bin/bash
# trapchild

trap 'echo "[TRAP]I am going down, so killing off my processes.."; ps -a | grep sleep | xargs kill -9; wait; exit' SIGHUP SIGINT SIGQUIT SIGTERM SIGKILL

./a.sh
err=$?
if [ $err != 0 ]; then
    echo 3 $err
    exit 1
fi

echo "[TRAP]my process pid is: $$"
echo "[TRAP]my child pid list is: $pid"

wait
#!/bin/bash
# trapchild

trap 'echo "[a]ash I am going down, so killing off my processes.."; ps -a | grep sleep | xargs kill -9; wait; exit' SIGHUP SIGINT SIGQUIT SIGTERM SIGKILL

sleep 120
echo 1 $?
if [ $? != 0 ]; then
    echo 2 $?
    exit 1
fi

pid="$!"

echo "[a]my process pid is: $$"
echo "[a]my child pid list is: $pid"

wait

执行trap.sh 之后会有三个进程

$ ps -a
  PID TTY          TIME CMD
  750 pts/5    00:00:00 trap.sh
  751 pts/5    00:00:00 a.sh
  752 pts/5    00:00:00 sleep

此时执行 kill -15 750kill-15 751 不会起作用,只有执行 kill -15 752 才会起作用,但是 trap 不会触发

使用异步方式

#!/bin/bash
# trapchild

trap 'echo "[TRAP]I am going down, so killing off my processes.."; ps -a | grep sleep | xargs kill -9; wait; exit' SIGHUP SIGINT SIGQUIT SIGTERM SIGKILL

./a.sh &
err=$?
if [ $err != 0 ]; then
    echo 3 $err
    exit 1
fi

echo "[TRAP]my process pid is: $$"
echo "[TRAP]my child pid list is: $pid"

wait
#!/bin/bash
# trapchild

trap 'echo "[a]ash I am going down, so killing off my processes.."; ps -a | grep sleep | xargs kill -9; wait; exit' SIGHUP SIGINT SIGQUIT SIGTERM SIGKILL

sleep 120 &
echo 1 $?
if [ $? != 0 ]; then
    echo 2 $?
    exit 1
fi

pid="$!"

echo "[a]my process pid is: $$"
echo "[a]my child pid list is: $pid"

wait

执行trap.sh 之后会有三个进程

$ ps -a
  PID TTY          TIME CMD
  750 pts/5    00:00:00 trap.sh
  751 pts/5    00:00:00 a.sh
  752 pts/5    00:00:00 sleep

如果执行 kill -15 752,不会触发 trap 直接退出

$ ./trap.sh
[TRAP]my process pid is: 2163
[TRAP]my child pid list is:
1 0
[a]my process pid is: 2164
[a]my child pid list is: 2165

如果执行 kill -15 751,触发 a.sh trap

$ ./trap.sh
[TRAP]my process pid is: 2324
[TRAP]my child pid list is:
1 0
[a]my process pid is: 2325
[a]my child pid list is: 2326
[a]ash I am going down, so killing off my processes..
kill: failed to parse argument: 'pts/5'

如果执行 kill -15 750,触发 trap.sh trap

$ ./trap.sh
[TRAP]my process pid is: 2487
[TRAP]my child pid list is:
1 0
[a]my process pid is: 2488
[a]my child pid list is: 2489
[TRAP]I am going down, so killing off my processes..

other

当脚本直接同步、异步混合使用时需要考虑周全,详细测试

Ref

  1. Shell编程之trap命令
  2. 在脚本中使用 trap

原文:大专栏  shell向子进程发送信号

原文地址:https://www.cnblogs.com/petewell/p/11606639.html

时间: 2024-10-07 00:16:36

shell向子进程发送信号的相关文章

我使用过的Linux命令之kill - 终止进程/发送信号

用途说明 kill命令用于终止指定的进程(terminate a process),是Unix/Linux下进程管理的常用命令.通常,我们在需要终止某个或某些进程时,先使用ps/pidof/pstree/top等工具获取进程PID,然后使用kill命令来杀掉该进程.kill命令的另外一个用途就是向指定的进程或进程组发送信号(The  command kill sends the specified signal to the specified process or process group)

shell脚本进阶之信号的捕捉

shell脚本之信号的捕捉 ? trap,翻译过来就是陷阱的意思,shell脚本中的陷阱是专门用来捕捉信号的.啥信号呢?比如经常使用的kill -9,kill -15,CTRL+C等都属于信号 1.查看所有可用的信号 trap -l或kill -l即可 [[email protected] ~]# kill -l 63) SIGRTMAX-1 64) SIGRTMAX [[email protected] ~]# trap -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4)

shell 脚本编程之信号捕捉和主机探测

shell 脚本编程之信号捕捉和主机探测 =============================================================================== 概述: =============================================================================== 主机探测 1.写一个脚本,探测192.168.0.0网段中主机在线状态 [[email protected] bin]# cat 

发送信号

发送信号 –使用kill命令 •在命令行使用kill命令,向指定进程发送信号. –使用kill函数 #include <signal.h> #include <sys/types.h> int kill(pid_t pid, int sig); •参数pid指定一个要杀死的进程,而sig是要发送的信号. kill函数例子 int main(int arg, char *args[]) { if (arg > 1) { int pid = atoi(args[1]); kill

Linux 发送信号

使用kill命令 --在命令行执行kill命令.向指定进程发送信号. 使用kill函数 int kill(pid_t pid,int sig); --参数pid指定一个要杀死的进程,而sig是要发送的信号. //kill函数发送信号 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include &

QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)

QThread 继承 QObject..它可以发送started和finished信号,也提供了一些slot函数. QObject.可以用于多线程,可以发送信号调用存在于其他线程的slot函数,也可以postevent给其他线程中的对象.之所以可以这样做,是因为每个线程都有自己的事件循环. 在进行下面的讲解之前,应该了解的重要的一点是:QThread 对象所在的线程,和QThread 创建的线程,也就是run()函数执行的线程不是同一个线程.QThread 对象所在的线程,就是创建对象的线程.我

Linux 命令 - killall: 通过进程名向进程发送信号

命令格式 killall [-Z CONTEXT] [-u USER] [ -eIgiqrvw ] [ -SIGNAL ] NAME... killall -l, --list killall -V, --version 命令参数 -e, --exact 对于长名字,要求精确匹配.如果一个命令名的长度超过 15 字符,则可能不会用完整的名字.这种情况下,killall 会杀死名字匹配前 15 个字符的进程.使用 -e 选项,则会要求进程名字完全匹配. -I, --ignore-case 匹配进程

linux驱动的异步通知(kill_fasync,fasync)---- 驱动程序向应用程序发送信号

应用程序 [cpp] view plain copy #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <poll.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> #include <fcn

block的是发送信号的线程,又不是处理槽函数的线程

请问UI线程给子线程发信号,应该用哪种连接方式? 如果子线程正在执行一个函数,我发射信号去执行子线程的另一个函数,那么此时子线程到底会执行什么呢? 用信号量做的同步.第一把信号槽的事件丢到线程的事件队列,第二信号量等待,等到事件处理完触发,继续执行主线程逻辑.子线程还是处理事件,只是信号槽的槽函数执行完,会做信号量的操作… 连接的时候,那就不需要block? 因为信号量已经控制好了?需要,你只有指定那个连接参数才有信号量的操作… block的是发送信号的线程,又不是处理槽函数的线程…给槽函数线程