【问题标题】:Why is kill -2 not killing the process?为什么 kill -2 不杀死进程?
【发布时间】:2020-08-07 05:41:35
【问题描述】:

编辑:根据我的测试,似乎不可能使用脚本中的 SIGINT/SIGQUIT 信号终止进程。我不知道为什么。


我正在使用 bash 开发 Centos 7。

我想知道为什么kill -2 $pid 没有杀死进程。

我有一个启动子进程的主脚本。多亏了一个什么都不做的循环,该子流程才能保持运行。

这是主代码:

#!/bin/bash

index=1
max=1
while [[ $index -le $max ]]; do
    if [[ $index -eq 9 ]]; then
        index=$((index + 1))
    fi
    bash trap.sh loop $index &
    sleep 2
    processes=$(ps -ef | grep "bash trap.sh loop" | grep -v "grep")
    processes=$(tr -s ' ' <<<$processes)
    sub_pid=$(cut -d ' ' -f 2 <<<$processes)
    echo "$processes"
    kill -2 $sub_pid
    index=$((index + 1))
    sleep 5
done

输出如下:

2020-08-07 07:32:45.521 | DEBUG  | trap.sh (main:4) | trap set: SIGNAL=1 : code=default_trap
2020-08-07 07:32:45.553 | DEBUG  | trap.sh (main:4) | trap set: SIGNAL=2 : code=default_trap
2020-08-07 07:32:45.599 | DEBUG  | trap.sh (main:4) | trap set: SIGNAL=3 : code=default_trap
2020-08-07 07:32:45.716 | DEBUG  | trap.sh (main:4) | trap set: SIGNAL=8 : code=default_trap
2020-08-07 07:32:45.801 | DEBUG  | trap.sh (main:4) | trap set: SIGNAL=14 : code=default_trap
2020-08-07 07:32:45.815 | DEBUG  | trap.sh (main:4) | trap set: SIGNAL=15 : code=default_trap
2020-08-07 07:32:45.826 | INFO   | trap.sh (main:16) | trap test number 1
2020-08-07 07:32:45.871 | DEBUG  | trap.sh (main:23) | set trap --call-on-signal trap_test 
2020-08-07 07:32:45.995 | DEBUG  | trap.sh (main:23) | trap set: SIGNAL=EXIT : code=trap_test
2020-08-07 07:32:46.068 | DEBUG  | locker.sh (locker_set_lock:35) | LOCK_FILE set to thedoor
2020-08-07 07:32:46.132 | DEBUG  | trap.sh (main:23) | trap update : SIGNAL=EXIT : new code=trap_test;locker_unlock
2020-08-07 07:32:46.164 | DEBUG  | locker.sh (locker_set_lock:57) | locking at thedoor
root 4033 4032 56 07:32 pts/0 00:00:01 bash trap.sh loop 1

注意:输出来自脚本trap.sh,它被主进程作为子进程启动。

如您所见,主进程应该已经杀死了子进程。此外,子进程具有可能的陷阱,如预期的那样,一个位于信号 2 上。 但是子进程并没有被杀死。

[root@localhost tests]# ps -ef | grep trap
root      4033     1 96 07:32 pts/0    00:03:37 bash trap.sh loop 1
root      4239  3281  0 07:36 pts/0    00:00:00 grep --color=auto trap

当我手动启动 trap.sh 作为子进程并尝试手动终止它时,它会按我的预期工作:

[root@localhost tests]# bash trap.sh loop 0 &
[1] 4430
[root@localhost tests]# 2020-08-07 07:37:53.017 | DEBUG  | trap.sh (main:4) | trap set: SIGNAL=1 : code=default_trap
2020-08-07 07:37:53.219 | DEBUG  | trap.sh (main:4) | trap set: SIGNAL=2 : code=default_trap
2020-08-07 07:37:53.445 | DEBUG  | trap.sh (main:4) | trap set: SIGNAL=3 : code=default_trap
....some more logs...

[root@localhost tests]# kill -2 4430
[root@localhost tests]# 2020-08-07 07:38:05.436 | INFO   | trap.sh (main:1) | an interruption signal has been caught. Triggering EXIT
2020-08-07 07:38:05.727 | DEBUG  | trap.sh (main:1) | I AM THE TRAP TEST. FEAR ME.
2020-08-07 07:38:06.052 | TRACE  | error_handling.sh (safe_check:61) | rm -f thedoor
2020-08-07 07:38:06.395 | DEBUG  | locker.sh (locker_unlock:18) | unlock thedoor complete

我的问题是:为什么我无法终止由带有信号 2 的脚本启动的进程?

为什么我能够杀死从命令行使用信号 2 启动的进程?

有什么区别?我怎样才能从脚本“让它工作”?


编辑:trap.sh 的内容

在我的情况下发生的是它在第 26 行进入循环,并永远循环直到它被杀死。

#!/bin/bash

export SOURCES_PATH="${SOURCES_PATH:-..}" && source "$SOURCES_PATH/toolbox.sh"
TOOLBOX_SETUP -l -1 
if [[ -z $1 ]]; then
    FATAL "MISSING ARGUMENT TO THE SCRIPT. Inform if you want the script to normally exit ('exit') or loop ('loop')"
    exit
fi

if [[ -z $2 ]]; then
    FATAL "MISSING SECOND ARGUMENT TO THE SCRIPT. It should be a number (this script should be only used by trap_master.sh)"
    exit
fi

TOOLBOX_SETUP --file "trap_test_$2.log"
INFO "trap test number $2"


function trap_test() {
    DEBUG "I AM THE TRAP TEST. FEAR ME."
}

TOOLBOX_SETUP --call-on-signal 'trap_test' --lock-file thedoor
if [[ $1 = "loop" ]]; then
    while true;do
    :
    done
elif [[ $1 = "exit" ]]; then
    exit
else
    FATAL "UNKNOWN PARAM $1"
    exit
fi

【问题讨论】:

  • 只是想知道:有什么原因,为什么你不能简单地通过sub_pid=$! 获得进程ID?此外,在您的脚本中,您打印用于调试$processes,但您不打印$sub_pid。你如何验证你是否真的试图杀死正确的进程?
  • @user1934428 好吧,不,没有理由。我只是不知道,感谢您的改进:)。关于杀死正确进程的事实,我忘记将回声放回 SO。但是,为了之前对其进行测试并让它处理从 1 到 15 的所有信号(当然除了 9),2 是唯一没有给出我预期结果的信号
  • trap.sh的内容是什么?最有可能的是,您遇到的行为是,在运行命令终止后(例如,在命令之间)执行传递给 bash 的信号的陷阱。
  • @KamilCuk 我已经用 trap.sh 的内容更新了这个问题。但是,如果您说的是正确的,为什么它会与其他信号一起使用,而不是与 SIGINT 一起使用?
  • 来自文档:“当作业控制无效时,除了这些继承的处理程序之外,异步命令还会忽略 SIGINT 和 SIGQUIT。”

标签: linux bash centos7


【解决方案1】:

来自文档:

SIGNALS
       When bash is interactive, in the absence of any traps, it ignores SIGTERM (so that  kill  0  does  not  kill  an  interactive
       shell),  and  SIGINT  is caught and handled (so that the wait builtin is interruptible).  In all cases, bash ignores SIGQUIT.
       If job control is in effect, bash ignores SIGTTIN, SIGTTOU, and SIGTSTP.

       Non-builtin commands run by bash have signal handlers set to the values inherited by the shell from  its  parent.   When  job
       control  is not in effect, asynchronous commands ignore SIGINT and SIGQUIT in addition to these inherited handlers.  Commands
       run as a result of command substitution ignore the keyboard-generated job control signals SIGTTIN, SIGTTOU, and SIGTSTP.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 2020-01-10
    • 2014-12-17
    • 1970-01-01
    相关资源
    最近更新 更多