Issue
EDIT: From my tests, it seems not to be possible to terminate a process with the SIGINT/SIGQUIT signal from a script. I do not know why though.
I am working on Centos 7, with bash.
I would like to know why isn't kill -2 $pid
killing the process.
I have a master script that starts a subprocess. That subprocess stays up thanks to a loop that does nothing.
Here is that master code:
#!/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
The output is as following:
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
Note: the output comes from the script trap.sh that is being started as sub process by the master.
As you can see, the master should have killed the sub process. Moreover, the sub process has may traps, one being on signal 2, as expected. But the sub process is not killed.
[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
When I launch trap.sh manually as a sub process and try to kill it also manually, it works as I expect it to:
[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
My question is: Why am I not able to kill a process that was started by a script with signal 2 ?
And why am I able to kill a process that was started from command line with signal 2 ?
What is the difference ? How can I "make it work" from script ?
edit: content of trap.sh
What happens in my case is that it goes into the loop at line 26, and loops forever until it gets killed.
#!/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
Solution
From the documentation:
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.
Answered By - William Pursell Answer Checked By - Pedro (WPSolving Volunteer)