How do I automate killing a job in cron? [duplicate] - github

This question already has answers here:
Find and kill a process in one line using bash and regex
(30 answers)
Closed 1 year ago.
Sometimes when I try to start Firefox it says "a Firefox process is already running". So I have to do this:
jeremy#jeremy-desktop:~$ ps aux | grep firefox
jeremy 7451 25.0 27.4 170536 65680 ? Sl 22:39 1:18 /usr/lib/firefox-3.0.1/firefox
jeremy 7578 0.0 0.3 3004 768 pts/0 S+ 22:44 0:00 grep firefox
jeremy#jeremy-desktop:~$ kill 7451
What I'd like is a command that would do all that for me. It would take an input string and grep for it (or whatever) in the list of processes, and would kill all the processes in the output:
jeremy#jeremy-desktop:~$ killbyname firefox
I tried doing it in PHP but exec('ps aux') seems to only show processes that have been executed with exec() in the PHP script itself (so the only process it shows is itself.)

pkill firefox
More information: http://linux.about.com/library/cmd/blcmdl1_pkill.htm

Also possible to use:
pkill -f "Process name"
For me, it worked up perfectly. It was what I have been looking for.
pkill doesn't work with name without the flag.
When -f is set, the full command line is used for pattern matching.

You can kill processes by name with killall <name>
killall sends a signal to all
processes running any of the specified
commands. If no signal name is
specified, SIGTERM is sent.
Signals can be specified either by
name (e.g. -HUP or -SIGHUP ) or by number (e.g.
-1) or by option -s.
If the command name is not regular
expression (option -r) and contains a
slash (/), processes executing that
particular file will be selected for
killing, independent of their name.
But if you don't see the process with ps aux, you probably won't have the right to kill it ...

A bit longer alternative:
kill `pidof firefox`

The easiest way to do is first check you are getting right process IDs with:
pgrep -f [part_of_a_command]
If the result is as expected. Go with:
pkill -f [part_of_a_command]
If processes get stuck and are unable to accomplish the request you can use kill.
kill -9 $(pgrep -f [part_of_a_command])
If you want to be on the safe side and only terminate processes that you initially started add -u along with your username
pkill -f [part_of_a_command] -u [username]

Kill all processes having snippet in startup path. You can kill all apps started from some directory by for putting /directory/ as a snippet. This is quite usefull when you start several components for the same application from the same app directory.
ps ax | grep <snippet> | grep -v grep | awk '{print $1}' | xargs kill
* I would prefer pgrep if available

Strange, but I haven't seen the solution like this:
kill -9 `pidof firefox`
it can also kill multiple processes (multiple pids) like:
kill -9 `pgrep firefox`
I prefer pidof since it has single line output:
> pgrep firefox
6316
6565
> pidof firefox
6565 6316

Using killall command:
killall processname
Use -9 or -KILL to forcefully kill the program (the options are similar to the kill command).

On Mac I could not find the pgrep and pkill neither was killall working so wrote a simple one liner script:-
export pid=`ps | grep process_name | awk 'NR==1{print $1}' | cut -d' ' -f1`;kill $pid
If there's an easier way of doing this then please share.

To kill with grep:
kill -9 `pgrep myprocess`

more correct would be:
export pid=`ps aux | grep process_name | awk 'NR==1{print $2}' | cut -d' ' -f1`;kill -9 $pid

I normally use the killall command.
Check this link for details of this command.

I was asking myself the same question but the problem with the current answers is that they don't safe check the processes to be killed so... it could lead to terrible mistakes :)... especially if several processes matches the pattern.
As a disclaimer, I'm not a sh pro and there is certainly room for improvement.
So I wrote a little sh script :
#!/bin/sh
killables=$(ps aux | grep $1 | grep -v mykill | grep -v grep)
if [ ! "${killables}" = "" ]
then
echo "You are going to kill some process:"
echo "${killables}"
else
echo "No process with the pattern $1 found."
return
fi
echo -n "Is it ok?(Y/N)"
read input
if [ "$input" = "Y" ]
then
for pid in $(echo "${killables}" | awk '{print $2}')
do
echo killing $pid "..."
kill $pid
echo $pid killed
done
fi

kill -9 $(ps aux | grep -e myprocessname| awk '{ print $2 }')

If you run GNOME, you can use the system monitor (System->Administration->System Monitor) to kill processes as you would under Windows. KDE will have something similar.

The default kill command accepts command names as an alternative to PID. See kill (1). An often occurring trouble is that bash provides its own kill which accepts job numbers, like kill %1, but not command names. This hinders the default command. If the former functionality is more useful to you than the latter, you can disable the bash version by calling
enable -n kill
For more info see kill and enable entries in bash (1).

ps aux | grep processname | cut -d' ' -f7 | xargs kill -9 $

awk oneliner, which parses the header of ps output, so you don't need to care about column numbers (but column names). Support regex. For example, to kill all processes, which executable name (without path) contains word "firefox" try
ps -fe | awk 'NR==1{for (i=1; i<=NF; i++) {if ($i=="COMMAND") Ncmd=i; else if ($i=="PID") Npid=i} if (!Ncmd || !Npid) {print "wrong or no header" > "/dev/stderr"; exit} }$Ncmd~"/"name"$"{print "killing "$Ncmd" with PID " $Npid; system("kill "$Npid)}' name=.*firefox.*

Related

How to stop stunnel in linux server(using terminal only), other than killing pid

We have configures our stunnel properly in Ubuntu 16.04 , also it is starting properly we are getting our data in application which comes from stunnel server. Although I cannot find any proper way to stop stunnel. I tried killing the pid of stunnel , but killing pid is not a proper way to stop.
Thanks
There are could be several of stunnel processes:
[root#someserver ~]# ps aux | grep stunnel | grep -v grep | awk '{print $2}'
13527
13528
13529
13530
13531
13532
The following bash-one-line loop could handle to kill them all:
if kill $(ps aux | grep stunnel | grep -v grep | awk '{print $2}'); then echo "Done"; else echo "No ps left"; fi
Killing the PID sounds pretty bad, but it is the common way to stop processes in linux. "Kill" is just another name for "send signal". If you issue a kill $pid, then a SIGTERM is sent to that process.
The process can then handle the signal and perform a clean shutdown. This is also the way many programs implement a configuration reloading functionality, they often use SIGHUP for that (kill -SIGHUP $pid).
So, as long as you don't use kill -SIGKILL $pid (or in short: kill -9 $pid) the program can handle that signal and gracefully shutdown.
More about signals on linux: https://en.wikipedia.org/wiki/Signal_(IPC)#List_of_signals

Can't kill celery workers

Try as I might I cannot kill these celery workers.
I run:
celery --app=my_app._celery:app status
I see I have 3 (I don't understand why 3 workers = 2 nodes, please explain if you know)
celery#ip-x-x-x-x: OK
celery#ip-x-x-x-x: OK
celery#named-worker.%ip-x-x-x-x: OK
2 nodes online.
I run (as root):
ps auxww | grep 'celery#ip-x-x-x-x' | awk '{print $2}' | xargs kill -9
The workers just keep reappearing with a new PID.
Please help me kill them.
A process whose pid keeps changing is called comet. Even though pid of this process keeps on changing, its process group ID remains constant. So you can kill by sending a signal.
ps axjf | grep '[c]elery' | awk '{print $3}' | xargs kill -9
Alternatively, you can also kill with pkill
pkill -f celery
This kills all processes with fullname celery.
Reference: killing a process
pkill -f celery
Run from the command line, this will kill at processes related to celery.
In your console, type :
ps -aux | grep celery
I get :
simon 24615 3.8 0.6 344276 219604 pts/3 S+ 22:53 0:56 /usr/bin/python3 /home/simon/.local/bin/celery -A worker_us_task worker -l info -Q us_queue --concurrency=30 -n us_worker#%h
select what you find after -A and type :
pkill -9 -f 'worker_us_task worker'
I always use:
ps auxww | grep 'celery' | awk '{print $2}' | xargs kill -9
If you're using supervisord to run celery, you need to kill supervisord process also.

Using /proc/<pid>, how can I identify a network port number's application?

I'm trying to identify what application is running on port 56474 without having root access. I know the application was started by me.
Example:
netstat -tunap
tcp 0 0 0.0.0.0:56474 0.0.0.0:* LISTEN -
I've tried using /proc/pid scripts to walk all using grep on ls -l /proc/pid/fd results. Here is my attempt. NOTE: Not sure if I was heading the right direction
for I in `find /proc/*/fd -exec ls -l {} \; 2>/dev/null | awk -F"->|:" '/socket/ {print $4}' | sort -u | sed -e 's/\[//g' -e 's/\]//g'`; do grep $I /proc/*/net/tcp; done
I had no success. Not sure if there is a way. Thanks.
NOTE: Added another answers as lsof was not satisfactory.
This should work:
#! /bin/bash
port=56474
hex_port=$(echo "obase=16; $port" | bc )
inode=$(cat /proc/net/tcp | grep ":$hex_port" | awk '{print $10}')
for i in $(ps axo pid); do
ls -l /proc/$i/fd 2> /dev/null | grep -q ":\[$inode\]" && echo $i
done
Explanation:
Once we have the port number converted to Hexadecimal, we can get the inode number from /proc/net/tcp (10th field), then we loop through /proc/pids/fd and find a symlink pointing to the inode.
If you're sure the application was started by you then you can use lsof:
/usr/sbin/lsof -nP | grep :56474 | awk '{print $2}'
Another technique to resolve pids and ports of all running apps without root:
1.) Get the pids of running apps. Either use the ActivityManager or parse a ps console output.
2.) iterate through /proc/$pid/net/status files and get the matching uid for a pid.
cat /proc/*pid*/net/status | grep Uid:
3.) Call and parse the output of tcp, tcp6,udp, udp6 files to match ports and uids:
cat /proc/net/tcp
...
4.) match the uids of both matchings, get a port-to-pid map without su access.
Cheers,
goethe

How to find the command line of a process only if the process is from current user

I have the following situation:
A perl script read a file where a application wrote it's pid, and tries to kill it.
But the problem is that I don't want to kill another process so I check if current process with the recorded PID has the same command line. If so, the application could be killed.
The following blues script find out the cmdline:
$PIDCMDLINE = `ps -p $PID -o cmd`;
The problem is that if another instance for another user is up, maybe on the same sid, it would be killed because it will return a valid command line, and I don't want that behaviour.
How can I restrict ps -p to search only current users processes (no, simple ps doesn't count, because -p nullify the default effect of ps)
Thank you!
You can use the following to check both command and user for the certain PID:
ps -p <PID> -o user,cmd --columns 1000 | grep `whoami`
Adding a 'grep' according to the comment.
May be a little awkward, but what about this:
$PIDCMDLINE = ps -p $PID -o user,command | grep `whoami` | awk '{ print $2 }'

Map sd?/sdd? names to Solaris disk names?

Some commands in Solaris (such as iostat) report disk related information using disk names such as sd0 or sdd2. Is there a consistent way to map these names back to the standard /dev/dsk/c?t?d?s? disk names in Solaris?
Edit: As Amit points out, iostat -n produces device names such as eg c0t0d0s0 instead of sd0. But how do I found out that sd0 actually is c0t0d0s0? I'm looking for something that produces a list like this:
sd0=/dev/dsk/c0t0d0s0
...
sdd2=/dev/dsk/c1t0d0s4
...
Maybe I could run iostat twice (with and without -n) and then join up the results and hope that the number of lines and device sorting produced by iostat is identical between the two runs?
Following Amit's idea to answer my own question, this is what I have come up with:
iostat -x|tail -n +3|awk '{print $1}'>/tmp/f0.txt.$$
iostat -nx|tail -n +3|awk '{print "/dev/dsk/"$11}'>/tmp/f1.txt.$$
paste -d= /tmp/f[01].txt.$$
rm /tmp/f[01].txt.$$
Running this on a Solaris 10 server gives the following output:
sd0=/dev/dsk/c0t0d0
sd1=/dev/dsk/c0t1d0
sd4=/dev/dsk/c0t4d0
sd6=/dev/dsk/c0t6d0
sd15=/dev/dsk/c1t0d0
sd16=/dev/dsk/c1t1d0
sd21=/dev/dsk/c1t6d0
ssd0=/dev/dsk/c2t1d0
ssd1=/dev/dsk/c3t5d0
ssd3=/dev/dsk/c3t6d0
ssd4=/dev/dsk/c3t22d0
ssd5=/dev/dsk/c3t20d0
ssd7=/dev/dsk/c3t21d0
ssd8=/dev/dsk/c3t2d0
ssd18=/dev/dsk/c3t3d0
ssd19=/dev/dsk/c3t4d0
ssd28=/dev/dsk/c3t0d0
ssd29=/dev/dsk/c3t18d0
ssd30=/dev/dsk/c3t17d0
ssd32=/dev/dsk/c3t16d0
ssd33=/dev/dsk/c3t19d0
ssd34=/dev/dsk/c3t1d0
The solution is not very elegant (it's not a one-liner), but it seems to work.
One liner version of the accepted answer (I only have 1 reputation so I can't post a comment):
paste -d= <(iostat -x | awk '{print $1}') <(iostat -xn | awk '{print $NF}') | tail -n +3
Try using the '-n' switch. For eg. 'iostat -n'
As pointed out in other answers, you can map the device name back to the instance name via the device path and information contained in /etc/path_to_inst. Here is a Perl script that will accomplish the task:
#!/usr/bin/env perl
use strict;
my #path_to_inst = qx#cat /etc/path_to_inst#;
map {s/"//g} #path_to_inst;
my ($device, $path, #instances);
for my $line (qx#ls -l /dev/dsk/*s2#) {
($device, $path) = (split(/\s+/, $line))[-3, -1];
$path =~ s#.*/devices(.*):c#$1#;
#instances =
map {join("", (split /\s+/)[-1, -2])}
grep {/$path/} #path_to_inst;
*emphasized text*
for my $instance (#instances) {
print "$device $instance\n";
}
}
I found the following in the Solaris Transistion Guide:
"Instance Names
Instance names refer to the nth device in the system (for example, sd20).
Instance names are occasionally reported in driver error messages. You can determine the binding of an instance name to a physical name by looking at dmesg(1M) output, as in the following example.
sd9 at esp2: target 1 lun 1
sd9 is /sbus#1,f8000000/esp#0,800000/sd#1,0
<SUN0424 cyl 1151 alt 2 hd 9 sec 80>
Once the instance name has been assigned to a device, it remains bound to that device.
Instance numbers are encoded in a device's minor number. To keep instance numbers consistent across reboots, the system records them in the /etc/path_to_inst file. This file is read only at boot time, and is currently updated by the add_drv(1M) and drvconf"
So based upon that, I wrote the following script:
for device in /dev/dsk/*s2
do
dpath="$(ls -l $device | nawk '{print $11}')"
dpath="${dpath#*devices/}"
dpath="${dpath%:*}"
iname="$(nawk -v dpath=$dpath '{
if ($0 ~ dpath) {
gsub("\"", "", $3)
print $3 $2
}
}' /etc/path_to_inst)"
echo "$(basename ${device}) = ${iname}"
done
By reading the information directly out of the path_to_inst file, we are allowing for adding and deleting devices, which will skew the instance numbers if you simply count the instances in the /devices directory tree.
I think simplest way to find descriptive name having instance name is:
# iostat -xn sd0
extended device statistics
r/s w/s kr/s kw/s wait actv wsvc_t asvc_t %w %b device
4.9 0.2 312.1 1.9 0.0 0.0 3.3 3.5 0 1 c1t1d0
#
The last column shows descriptive name for provided instance name.
sd0 sdd0 are instance names of devices.. you can check /etc/path_to_inst to get instance name mapping to physical device name, then check link in /dev/dsk (to which physical device it is pointing) it is 100% sure method, though i dont know how to code it ;)
I found this snippet on the internet some time ago, and it does the trick. This was on Solaris 8:
#!/bin/sh
cd /dev/rdsk
/usr/bin/ls -l *s0 | tee /tmp/d1c |awk '{print "/usr/bin/ls -l "$11}' | \
sh | awk '{print "sd" substr($0,38,4)/8}' >/tmp/d1d
awk '{print substr($9,1,6)}' /tmp/d1c |paste - /tmp/d1d
rm /tmp/d1[cd]
A slight variation to allow for disk names that are longer than 8 characters (encountered when dealing with disk arrays on a SAN)
#!/bin/sh
cd /dev/rdsk
/usr/bin/ls -l *s0 | tee /tmp/d1c | awk '{print "/usr/bin/ls -l "$11}' | \
sh | awk '{print "sd" substr($0,38,4)/8}' >/tmp/d1d
awk '{print substr($9,1,index($9,"s0)-1)}' /tmp/d1c | paste - /tmp/d1d
rm /tmp/d1[cd]