Skip to content
Advertisement

Why is kill -2 not killing the process?

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

Advertisement

Answer

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.
Advertisement