为什么 kill -2 不终止进程?
Why is kill -2 not killing the process?
编辑:根据我的测试,似乎无法使用来自脚本的 SIGINT/SIGQUIT 信号终止进程。虽然我不知道为什么。
我正在使用 Centos 7,bash。
我想知道为什么 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,该脚本正由主进程作为子进程启动。
如你所见,master应该把子进程kill掉了。此外,子进程可能有陷阱,正如预期的那样,一个在信号 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 ]]; then
FATAL "MISSING ARGUMENT TO THE SCRIPT. Inform if you want the script to normally exit ('exit') or loop ('loop')"
exit
fi
if [[ -z ]]; 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_.log"
INFO "trap test number "
function trap_test() {
DEBUG "I AM THE TRAP TEST. FEAR ME."
}
TOOLBOX_SETUP --call-on-signal 'trap_test' --lock-file thedoor
if [[ = "loop" ]]; then
while true;do
:
done
elif [[ = "exit" ]]; then
exit
else
FATAL "UNKNOWN PARAM "
exit
fi
来自文档:
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.
编辑:根据我的测试,似乎无法使用来自脚本的 SIGINT/SIGQUIT 信号终止进程。虽然我不知道为什么。
我正在使用 Centos 7,bash。
我想知道为什么 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,该脚本正由主进程作为子进程启动。
如你所见,master应该把子进程kill掉了。此外,子进程可能有陷阱,正如预期的那样,一个在信号 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 ]]; then
FATAL "MISSING ARGUMENT TO THE SCRIPT. Inform if you want the script to normally exit ('exit') or loop ('loop')"
exit
fi
if [[ -z ]]; 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_.log"
INFO "trap test number "
function trap_test() {
DEBUG "I AM THE TRAP TEST. FEAR ME."
}
TOOLBOX_SETUP --call-on-signal 'trap_test' --lock-file thedoor
if [[ = "loop" ]]; then
while true;do
:
done
elif [[ = "exit" ]]; then
exit
else
FATAL "UNKNOWN PARAM "
exit
fi
来自文档:
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.