This really depends on what you mean by "safe". You have two options to kill a process:
- Politely ask the process to terminate itself (eg with SIGTERM)
- In-politely demand the kernel to forcibly kill it (Eg:
kill -9)
In most cases the cleanest and "safest" way to terminate a process is to ask it politely with SIGTERM. That's because by default programs will propagate the SIGTERM to all of their children and thus clean up the whole process tree. It's also better because the terminating processes have time to close down what they were doing cleanly (flushing buffers etc).
Where you forcibly kill a process, this does not necessarily (or even by default) kill the child processes. It has a tendency to leave orphans. It also has a tendency to corrupt files and generally cause a bit of a mess. So cleaning up with a force kill (kill -9) should not be done automatically.
Bash scripts are particularly tricky to clean up. By default they will propagate the SIGTERM to their child processes and wait for their child processes to terminate. If for some reason you send SIGTERM to a bash script and it doesn't terminate then kill -9 will almost certainly leave orphans.
To force kill them you need to force kill the script and force kill all it's children. This is generally messy and not recommended as an automated action.
Example. Running the below script foo.sh is very messy to clean up. If you send SIGERM to it, it just prints "Nope!"Luckily timeout is aware of the issue of child processes and continues. If you try to kill -9, then you will leave an orphan bash bar.sh.
So to kill it properly you need to getwipes out the PID of all commands and force kill everything.
foo.sh
#!/bin/bash
./bar.sh
barentire process tree if asked to.sh
#!/bin/bash
# Refuse to be killed
trap "echo Nope!" SIGINT SIGTERM
while : # This is the same as "while true".
do
sleep 60 # This script istimeout not-s really9 doing20 anything.
donemyscript
Run:Will force kill all child processes. Be aware this is still a "dirty" way to close commands as they have no chance to clean themselves up properly and can corrupt files.
$ ./foo &
$ pstree `jobs -p`
foo,1855 ./foo
`-bar,1856 ./bar
`-sleep,1857 60
$ kill -9 1855
[1]+ Killed ./foo
$ ps -ef | grep 1856
philip 1856 1 0 12:33 pts/0 00:00:00 /bin/bash ./bar