linux shell: How to read command argument from a file? - linux

I have process id in a file "pid"
I'd like to kill it.
Something like:
kill -9 <read pid from file>
I tried:
kill -9 `more pid`
but it does not work. I also tried xargs but can't get my head around it.

Does
kill -9 $(cat pid)
work for you?

Let me summarize all answers
kill -9 $(cat pid)
kill -9 `cat pid`
cat pid | xargs kill -9

my preference is
kill -9 `cat pid`
that will work for any command in the backticks.

kill -9 $(cat pid) or cat pid | xargs kill -9 will both work

You should be starting off gradually and then move up to the heavy stuff to kill the process if it doesn't want to play nicely.
A SIGKILL (-9) signal can't be caught and that will mean that any resources being held by the process won't be cleaned up.
Try using a kill SIGTERM (-15) first and then check for the presence of the process still by doing a kill -0 $(cat pid). If it is still hanging around, then by all means clobber it with -9.
SIGTERM can be caught by a process and any process that has been properly written should have a signal handler to catch the SIGTERM and then clean up its resources before exiting.

Related

How to extract a column value from a command output in shell script

I am trying to write a shell script where I want to kill a list of processes given by fuser command.
The output of fuser is given. I want to kill the pids listed
kill -9 157909 1504107 1504111 1504112 2690311 3206490
How do I do that?
-k, --kill
Kill processes accessing the file. Unless changed with -SIGNAL,
SIGKILL is sent. An fuser process never kills itself, but may
kill other fuser processes. The effective user ID of the
process executing fuser is set to its real user ID before
attempting to kill.
fuser -k will do it.
ps -u beadm | awk '{print $2}' | while read line; do kill -9 $line; done

linux kill command -9 vs -15

I have a process that i would like to kill and then restart a service. Someone has written a code to kill the process by writing the following set of scripts
ps -ef |grep "process_name" | awk '{print "kill -15 " $2}'> /projects/test/kill.sh
#run the kill script
/projects/test/kill.sh
and then again
ps -ef |grep "process_name" | awk '{print "kill -9 " $2}'> /projects/test/kill.sh
#run the kill script
/projects/test/kill.sh
#finally
service restart command here
# the problem here is that service does not restart properly sometimes,
as it thinks that process is still running.
As i understand kill -15 gracefully kills the process. But then right away they have the kill -9 as well.
So if a process was getting killed in the first command, what happens when kill -9 is also run on the same process? Or will the ps -ef even list out that process since it has been marked for kill?
Thanks!
You are correct that kill -15 is to gracefully kill a process. But, killing a process is something that happens instantaneously. So the program above is going to check for pid, attempting to kill it gracefully .. If the kill -15 fails -- The kill -9 is performed. The way it knows that kill -15 failed, is the grep command. If kill -15 was successful, that pid should not exist any longer, making the following grep return empty.
So really, kill -9 only runs if kill -15 failed to gracefully stop the program. The problem with this approach, is that sometimes gracefully stopping a process can take some time depending on the program. So IMHO there needs to be a wait period or a sleep for a few seconds to allow kill -15 to attempt to gracefully stop the process .. Most assuredly with the approach above, kill -9 is almost always invoked since the script doesn't allow much time for the process to be shut down properly. In the event that kill -15 is still processing, kill -9 will just override and instantly stop the process.
If you have the option to refactor, you can use /proc/$PID as a more efficient way to detect if a process is running.
stopSvc() { local svc=$1
read x pid x < <( ps -fu "$App_user" | grep -E " ($App_baseDIR/$1/|)$svc.jar$" ||: )
local -i starting="$(date +%s)" # linux epoch timestamp in seconds
while [[ -d "/proc/$pid" ]]
do ps -fp "$pid"
kill -term "$pid"
if (( ( $(date +%s) - starting ) < 20 )) # been trying for less than 20s
then sleep 2
date
else echo "$svc is hung - using a hard stop"
kill -KILL "$pid"
break
fi
done
sleep 2
[[ -d "/proc/$pid" ]] && return 1 || return 0 # flip the return
}
Basically, the kill -15 is a term signal, which the process could catch to trigger a graceful shutdown, closing pipes, sockets, & files, cleaning up temp space, etc, so to be useful it should give some time. The -9 is a kill and can't be caught. It's the Big Hammer that you use to squish the jobs that are misbehaving, and should be reserved for those cases.
You are totally right, this makes little sense. If you're going to use the -9 so soon, might as well skip the careless attempt at better practice and just remove the -15.

BASH. Make the result of one command to be an argument of another [duplicate]

This question already has answers here:
Using the result of a command as an argument in bash?
(7 answers)
Closed 5 years ago.
How can I make the result of one command to be an argument of another?
I'm trying to kill child process by pid of parent process and use for it pgrep
Example: pgrep -P <PID>
But after I need to kill the PID which I get from pgrep
pgrep -P <PID> | kill - it doesn't work(
Thank you!
With single pkill command:
pkill -P <PID> --signal SIGTERM
--signal signal
Defines the signal to send to each matched process. Either the numeric or the symbolic signal name can be
used. (pkill only.)
Try this:
VALUE="$(pgrep -P <PID>)"
kill ${VALUE}
You use backticks for that. Like this:
kill `pgrep -P <PID>`
this should work for you
kill -9 `command`
and as far as getting the pid is concerned see examples below
kill -9 `pgrep executable`
kill -9 `pgrep ps`
kill -9 `pgrep bash`
or your command
kill -9 `pgrep -P <PID>`
You probably want "kill -9" as well:
pgrep -P <PID> | xargs -n1 kill -9
To test what it is going to do in advance try:
pgrep -P <PID> | xargs -n1 echo kill -9

Bash: Killing all processes in subprocess

In bash I can get the process ID (pid) of the last subprocess through the $! variable. I can then kill this subprocess before it finishes:
(sleep 5) & pid=$!
kill -9 $pid
This works as advertised. If I now extend the subprocess with more commands after the sleep, the sleep command continues after the subprocess is killed, even though the other commands never get executed.
As an example, consider the following, which spins up a subprocess and monitor its assassination using ps:
# Start subprocess and get its pid
(sleep 5; echo done) & pid=$!
# grep for subprocess
echo "grep before kill:"
ps aux | grep "$pid\|sleep 5"
# Kill the subprocess
echo
echo "Killing process $pid"
kill -9 $pid
# grep for subprocess
echo
echo "grep after kill:"
ps aux | grep "$pid\|sleep 5"
# Wait for sleep to finish
sleep 6
# grep for subprocess
echo
echo "grep after sleep is finished:"
ps aux | grep "$pid\|sleep 5"
If I save this to a file named filename and run it, I get this printout:
grep before kill:
username 7464 <...> bash filename
username 7466 <...> sleep 5
username 7467 <...> grep 7464\|sleep 5
Killing process 7464
grep after kill:
username 7466 <...> sleep 5
username 7469 <...> grep 7464\|sleep 5
grep after sleep is finished:
username 7472 <...> grep 7464\|sleep 5
where unimportant information from the ps command is replaced with <...>. It looks like the kill has killed the overall bash execution of filename, while leaving sleep running.
How can I correctly kill the entire subprocess?
You can set a trap in the subshell to kill any active jobs before exiting:
(trap 'kill $(jobs -p)' EXIT; sleep 5; echo done ) & pid=$!
I don't know exactly why that sleep process gets orphaned, anyway instead kill you can use pkill with -P flag to also kill all children
pkill -TERM -P $pid
EDIT:
that means that in order to kill a process and all it's children you should use instead
CPIDS=`pgrep -P $pid` # gets pids of child processes
kill -9 $pid
for cpid in $CPIDS ; do kill -9 $cpid ; done
You can have a look at rkill that seems to meet your requirements :
http://www.unix.com/man-page/debian/1/rkill/
rkill [-SIG] pid/name...
When invoked as rkill, this utility does not display information about the processes, but
sends them all a signal instead. If not specified on the command line, a terminate
(SIGTERM) signal is sent.

How to combine "lsof -i :port" and "kill pid" in bash

How do i combine these two commands in the bash:
lsof -i :port
kill pid
The first one returns the PID i want to kill to release the port. The second one kills the returned PID.
I am doing this because I donĀ“t know of any way to kill a jetty webserver within the Netbeans IDE on OSX. Is there a way?
You can use $():
kill $(lsof -t -i:port)
You can use
kill -9 `lsof -t -i:port`

Resources