kill -9 `cat ~/code/posbox/posbox.pid`
I'm running the command above to kill a process. The pid is in the file, it's correctly killing the process but child processes are still running
when I do
kill <PID number>
it kills the process along with all the child processes. How do I kill all parent and child processes from a pid given in a pid file?
Since kill <PID number> works, just use that:
# By default, send SIGTERM, not SIGKILL (9)
kill $(cat ~/code/posbox/posbox.pid)
It sounds like your process catches the TERM signal and passes it on to its children before exiting, allowing them all to exit cleanly. Using kill -9 ends the parent immediately, without giving it a chance to tell its children to exit at all.
Related
I'd like to spawn several child processes in Bash, but I'd like the parent script to remain running, such that signals send to the parent script also affect the spawned children processes.
This doesn't do that:
parent.bash:
#!/usr/bin/bash
spawnedChildProcess1 &
spawnedChildProcess2 &
spawnedChildProcess3 &
parent.bash ends immediately, and the spawned processes continue running independently of it.
If you want your parent to not exit immediately after spawning its children, then as Barmar told you, use wait.
Now, if you want your child processes to die when the parent exits, then send them a SIGTERM (or any other) signal just before exiting:
kill 0
(0 is a special PID that means "every process in the parent's process group")
If the parent may exit unexpectedly (e.g. upon receiving a signal, because of a set -u or set -e, etc.) then you can use trap to send the TERM signal to the child just before exiting:
trap 'kill 0' EXIT
[edit] In conclusion, this is how you should write your parent process:
#!/usr/bin/bash
trap 'kill 0' EXIT
...
spawnedChildProcess1 &
spawnedChildProcess2 &
spawnedChildProcess3 &
...
wait
That way no need to send your signal to a negative process ID since this won't cover all the cases when your parent process may die.
Use wait to have the parent process wait for all the children to exit.
#!/usr/bin/bash
spawnedChildProcess1 &
spawnedChildProcess2 &
spawnedChildProcess3 &
wait
Keyboard signals are sent to the entire process group, so typing Ctl-c will kill the children and the parent.
I'm working with ash/dash and try to kill a subprocess - which doesn't seem to respond:
sh & opens a subprocess and jobs delivers [1]+ Stopped (tty Input) sh.
But trying to kill this Job with kill %1 or kill 26672 doesn't work. jobs delivers [1]+ Stopped (tty Input) sh again.
After putting the job to foreground with fg opens the shell for input. Neither ctrl+c nor ctrl+z are working but I can kill the process with exit or kill -SIGKILL $$ respectively stop/suspend the process with kill -STOP $$ (there is no suspend-command in ash).
On the other hand - doing this with i.e. sleep 100 works fine till I fg and stop the process with ctr+z. Then I'm not able to kill this stopped job.
So what am I missing and what could be the solution to kill a stopped job? Do I have to deal with set -m and how?
Thanks in advance.
You can try
kill -9 $(jobs -p)
Or, just do exit command to logout, it will automatically killed the stopped jobs
You can rung the Stopped process by kill -SIGCONT %numberand also if you need to kill that process you can kill it by kill -SIGTERM %number.Try this I think this will help you.
If I start the script by ./test.sh &, I am able to kill using kill -SIGINT PID.
But if I start my shell script using nohup ./test.sh & I am unable to kill the process using kill -SIGINT PID.
Kindly need your advice to kill the script using kill -SIGINT PID
The SIGINT signal means interrupt from keyboard; that's why it terminates a script run in foreground, but not in background neither using nohup.
To properly terminate your process use kill -TERM PID, which works in the 3 cases.
I would like to write a script that runs a few different infinitely running commands, e.g.
run_development_webserver.sh
watch_sass_files_and_compile_them.sh
watch_coffeescript_files_and_compile_them.sh
I'd like to run each of them in parallel, and kill them all by hitting ^C. Is this possible, and if so how can I do this?
I'll let Admiral Ackbar answer this one.
#!/bin/bash -e
run_development_webserver.sh &
PIDS[0]=$!
watch_sass_files_and_compile_them.sh &
PIDS[1]=$!
watch_coffeescript_files_and_compile_them.sh &
PIDS[2]=$!
trap "kill ${PIDS[*]}" SIGINT
wait
This starts each of your commands in the background (&), puts their process ids ($!) into an array (PIDS[x]=$!), tells bash to kill them all (${PIDS[*]) when your script gets a SIGINT signal (Ctrl+C), and then waits for all the processes to exit.
And I'll proactively mention that "kill ${PIDS[*]}" expands PIDS when you create the trap; if you change the double quotes (") to single quotes ('), it will be expanded when the trap is executed, which means you can add more processes to PIDS after you set the trap and it will kill them too.
If you have a stubborn process that doesn't want to quit after a Ctrl+C (SIGINT), you may need to send it a stronger kill signal - SIGTERM or even SIGKILL (use this as a last resort, it unconditionally kills the process without giving it a chance to clean up). First, try changing the trap line to this:
trap "kill -TERM ${PIDS[*]}" SIGINT
If it doesn't respond to the SIGTERM, save that process's pid separately, say in STUBBORN_PID, and use this:
trap "kill ${PIDS[*]}; kill -KILL $STUBBORN_PID" SIGINT
Remember, this one won't let the stubborn process clean up, but if it needs to die and isn't, you may need to use it anyway.
I would like to do the following:
I want to link a process A to a file F, so:
If F dissapears A crashes.
F will only dissapear when A finishes.
Is this possible? Thank you very much.
You should not avoid PIDs. They are process identifiers, and meant to be used.
Bash automatically monitors child processes it starts. The most recent background process id is maintained in $!. Bash also supports job controls using '%n' syntax.
You can trap child procs status changes with trap SIGCHLD, and you can "wait" for one or all child processes to complete with the wait command.
Here is a rough approximation of your two process monitoring, which consists of "job1" and "job2" being started the the sample script:
job1 & # start job1 in background
j1pid=$! # get its process id
job2 & # start job2 in background
j2pid=$1 # get its process id
trap 'err=1' ERR # trap all errors
err=
wait $j1pid # wait for job1 to complete
# at this point job1 could have completed normally,
# or either process could have had an error
trap - ERR # revert to "normal" handling of most errors
# kill the processes nicely, or abruptly
# kill -TERM sends the TERM signal to the process, which it can trap
# and do whatever pre-exit process is needed.
# kill -9 cannot be trapped.
for pid in $j1pid $j2pid ; do
kill -TERM $pid 2>/dev/null || kill -9 $pid
done
You already have a file with almost this property on Linux. If you created a process, the /proc/procNum will exist while the process is alive. As an example, if your process number is 1050, the /proc/1050 will exist until the process die. I do not know if removing this file will kill the process but you can try to tie both together.