Could SIGKILL fail? - linux

I've encountered this piece of behavior where even after issuing SIGKILL using kill -9 the process is not terminating. the command in question here is cat
# ps -ef | grep 19275
root 19275 1 0 08:50 ? 00:00:00 [cat]
root 22964 21578 0 09:05 pts/1 00:00:00 grep --color=auto 19275
# kill -9 19275
# echo $?
0
# ps -ef | grep 19275
root 19275 1 0 08:50 ? 00:00:00 [cat]
#
some background
I've executed this command for ((i=0; i<28; i++)); do cat </dev/zero >${i} & done as part of my test, for some strange reason when I tried to terminate this using
pkill -TERM cat did not work
pkill -9 cat did not work
kill -9 pid did not work
if memory is restriction here I do believe there is enough memory available here
# free -g
total used free shared buff/cache available
Mem: 23 18 2 0 2 3
Swap: 59 2 56
any hints ? apart from reboot

I tried your logic it worked for me with kill -9 and even with
killall cat, but it take some time to kill all 28 instances

Related

Kill 'ps aux' output in one line

I have to do the same thing many times a day:
ps aux
look for process running ssh to one of my servers ...
kill -9 <pid>
I'm looking to see if I can alias process into one line. The output of ps aux is usually something like this:
user 6871 0.0 0.0 4351260 8 ?? Ss 3:28PM 0:05.95 ssh -Nf -L 18881:my-server:18881
user 3018 0.0 0.0 4334292 52 ?? S 12:08PM 0:00.15 /usr/bin/ssh-agent -l
user 9687 0.0 0.0 4294392 928 s002 S+ 10:48AM 0:00.00 grep ssh
I always want to kill the process with the my-server in it.
Does anyone know how I could accomplish this?
for pid in $(ps aux | grep "[m]y-server" | awk '{print $2}'); do kill -9 $pid; done
ps aux | grep "[m]y-server" | awk '{print $2}' - this part gives you list of pids processes that include "my-server". And this script will go through this list and kill all this processes.
I use pgrep -- if you're sure you want to kill all the processes that match:
$ kill -9 `pgrep my-server`
A simple solution is to use pkill:
sudo pkill my-server

Give variable or name to process to kill not every process by this instance, but only with given name(variable)?

I have many processes by one program ( in this case node.js processes) running. Some times i need to run several ( for example 10 nodejs processes) , i start them with Makefile. I want to be able with some bash command within my Makefile to turn off those 10 process when needed, but i dont want to kill other node.js running processes. So i can use pkill node but it will kill every node processes, how can i give some name or some variable for this 10 processes, to kill only them with kill -9 or pkill?
You can store the PIDs of your child processes in a file and use it to kill them later. Example with sleep child processes:
$ cat Makefile
all: start-1 start-2 start-3
start-%:
sleep 100 & echo "$$!" >> pids.txt
kill:
kill -9 $$( cat pids.txt ); rm -f pids.txt
$ make
sleep 100 & echo "$!" >> pids.txt
sleep 100 & echo "$!" >> pids.txt
sleep 100 & echo "$!" >> pids.txt
$ ps
PID TTY TIME CMD
30331 ttys000 0:00.49 -bash
49812 ttys000 0:00.00 sleep 100
49814 ttys000 0:00.00 sleep 100
49816 ttys000 0:00.00 sleep 100
$ make kill
kill -9 $( cat pids.txt ); rm -f pids.txt
$ ps
PID TTY TIME CMD
30331 ttys000 0:00.50 -bash
Note: if you use parallel make you should pay attention to race conditions on pids.txt accesses.
You could try killing the processes by there PID (Process ID):
for example:
# ps -ax | grep nginx
22546 ? Ss 0:00 nginx: master process /usr/sbin/nginx
22953 pts/2 S+ 0:00 grep nginx
29419 ? Ss 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
29420 ? S 1:59 nginx: worker process
29421 ? S 1:54 nginx: worker process
29422 ? S 1:56 nginx: worker process
29423 ? S 1:49 nginx: worker process
29425 ? S 0:09 nginx: cache manager process
30796 ? S 1:49 nginx: worker process
and then you can kill the process with:
kill 22546; kill 22953; kill ...
You can also capture just the PID with:
# ps -ax | grep nginx | cut -d' ' -f1 |
22546
24582
29419
29420
29421
29422
29423
29425
30796
update:
you can write the PIDs to a file and pull them back in make like this:
pids:
echo ps -ax | grep nginx | cut -d' ' -f1 | > PIDs.txt \
FILE="/location/of/PIDs.txt" \
old_IFS=$IFS \
IFS=$'\n' \
lines=($(cat FILE)) \
IFS=$old_IFS \
PID=$(echo {line[4]}) \
kill $PID

pgrep command not returning PID

I am trying to find the PID of a process (motion_sensor.py), but pgrep returns nothing. Why does it not return the process id?
pgrep -u www-data motion_sensor.py
ps -ef | grep "motion_sensor" returns
root 7149 1 93 Apr25 ? 15:59:08 python motion_sensor.py
www-data 31872 23531 0 14:09 ? 00:00:00 sh -c sudo python /home/pi/Desktop/PiControl/motion_sensor.py
root 31873 31872 0 14:09 ? 00:00:00 sudo python /home/pi/Desktop/PiControl/motion_sensor.py
root 31874 31873 47 14:09 ? 00:14:30 python /home/pi/Desktop/PiControl/motion_sensor.py
pi 32645 32202 0 14:39 pts/0 00:00:00 grep --color=auto motion_sensor.py
Normally pgrep applies the search pattern to process names. The process name in this case is python and not motion_sensor.py. If you want to grep for the full path rather than just the process name you need to pass -f:
pgrep -u www-data -f motion_sensor.py
Check man pgrep
the requirement is to find out PID of a process,
So you can try :
ps aux | grep www-data motion_sensor.py

bash process substitution can't work fine with tee

The real thing I want to do is like ps -ef|head -n1 && ps -ef|grep httpd. The output should be something like this.
UID PID PPID C STIME TTY TIME CMD
xxxxx 6888 6886 0 16:49 pts/1 00:00:00 grep --color=auto httpd
root 10992 1 0 13:56 ? 00:00:00 sudo ./myhttpd
root 10993 10992 0 13:56 ? 00:00:00 ./myhttpd
root 11107 10993 0 13:56 ? 00:00:00 ./myhttpd
root 12142 10993 0 14:00 ? 00:00:00 ./myhttpd
root 31871 10993 0 15:03 ? 00:00:00 ./myhttpd
But I hate duplicates. So, I want ps -ef to appear only once.
Considering bash process substitution, I tried ps -ef | tee > >(head -n1) >(grep httpd), but the only output is
UID PID PPID C STIME TTY TIME CMD
However, ps -ef | tee > >(head -n1) >(head -n2) can work fine in the following way
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 13:36 ? 00:00:00 /sbin/init
UID PID PPID C STIME TTY TIME CMD
Can anyone help me ?
You can do head and grep on the same stream.
ps -ef | (head -n 1; grep '[h]ttpd')
It might be marginally more efficient to refactor to use sed:
ps -ef | sed -n -e '1p' -e '/[h]ttpd/p'
... but not all sed dialects deal amicably with multiple -e options. Perhaps this is more portable:
ps -ef | sed '1b;/[h]ttpd/b;d'
Also note the old trick to refactor the regex so as not to match itself by using a character class.
This can be achieved simply with pgrep and ps.
ps -fp $(pgrep -d, -o -f httpd)
use AWK
ps -ef | awk 'NR==1 || /httpd/'
print out 1st line or any line contains "httpd"
or use sed
ps -ef | sed -n '1p;/httpd/p'
ps -f -C httpd --noheaders | head -n1

Get the pid of the shell script and save it into a lockfile

I do my backups with rsnapshot which creates a lockfile with the process pid inside. Now I would like to make a backup from the rsnapshots backup, so I´m looking for a way to create this lockfile for the second/external backup.
The shell script should like this:
check if a lockfile exists, if yes wait and try again(i´m doing this with a while true loop)
get the pid of this shell script and save it as a rsnapshot lockfile
start the second/external backup
delete the lockfile
How can I get the PID and save it as a rsnapshot lockfile ?
The PID is stored in $$
Like
echo $$ > thisscriptpidfile
For any application, you can find its Process ID using the Unix shell itself, using ps. Example below is a very reduced list from ps. PS will show you not only the PID, but also the owner, as well as the Parent Process ID (as in which process started this particular process.)
userX# ps -ef | more
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Oct19 ? 00:00:00 /sbin/init
root 2 0 0 Oct19 ? 00:00:00 [kthreadd]
root 3 2 0 Oct19 ? 00:00:02 [migration/0]
root 4 2 0 Oct19 ? 00:04:48 [ksoftirqd/0]
root 5 2 0 Oct19 ? 00:00:00 [migration/0]
root 6 2 0 Oct19 ? 00:00:00 [watchdog/0]
...
root 27 2 0 Oct19 ? 00:00:00 [pm]
root 28 2 0 Oct19 ? 00:00:00 rsnapshot
root 29 2 0 Oct19 ? 00:00:00 [xenbus]
Now let's start finding which Process is interesting to us. I am not familiar with rsnapshot, so I've put dummy data in the examples.
userX# ps -ef | grep rsnapshot
root 28 2 0 Oct19 ? 00:00:00 rsnapshot
ec2-user 7233 1497 0 11:32 pts/0 00:00:00 grep rsnapshot
Note that it does not give you the "header" information, only matching lines, thanks to grep.
Your second "column" is the PID. Noteworthy: ps shows every process, including the grep you just ran. Your commands/scripts need to be wary of this and strip out these items. I will use awk in the next example to do just that.
And now to expand further, getting the PID into a file. We need to confirm we have a PID, and if so, create the command to create the lock file:
userX# ps -ef | grep rsnapshot | awk '$0!~/grep/ && $2~/[0-9]/{print "echo "$2" > rsnapshot.lck"}'
echo 28 > rsnapshot.lck
If no PID for rsnapshot exists, then there will be no output. As writtent, awk will review each line, and if it does not contain the string "grep" AND there is any digit [0-9] in the second field, then print the command to be run - but not actually run the command.
The final step is to invoke the command, from the awk output.
userX# ps -ef | grep rsnapshot | awk '$0!~/grep/ && $2~/[0-9]/{print "echo "$2" > rsnapshot.lck"}' | sh
Adding "| sh" causes all output to be invoked as a command. If awk does not find rsnapshot, then there is no command to run.

Resources