【发布时间】: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。”