Reputation: 21
I have written a very short script that gets pid of $1 then kills the process. I have a few questions / requests for improvement. (OSX)
#!/bin/bash
getpid=$(ps aux -O start | grep -i "$1" | grep -v grep | grep -v $0 | awk '{ if (NR==1) {print $2}}')
kill $getpid
For example:
$ ~/killpro.sh java
Which kills the most recent instance of java.
Or:
$ ~/killpro.sh chrome
To kill Google Chrome, obviously.
First, is there any practical way to get this strung together into a single line, using read -p perhaps, so that it can in turn be aliased and become something like:
$ killpro
$ Enter name: chrome
$
Not that it's significantly easier, in fact it's slightly more work, but it bypasses the need to type a path and shell extension which is desirable.
Second, is there anything fundamentally wrong with my initial approach / am I missing something obvious that negates the need for any this?
Any feedback is appreciated.
Thanks in advance, I'm (as you can tell) new to this.
Upvotes: 2
Views: 8783
Reputation: 880
My advice is to use pkill instead. From the manual page:
NAME
pgrep, pkill -- find or signal processes by name
Upvotes: 5
Reputation: 189507
Most scripts with grep | awk
are a useless use of grep
and should be refactored to use just Awk.
#!/bin/bash
# Maybe add a case for $# > 1 and quit with an error message
# Or maybe loop over arguments if there is more than one
case $# in 0) read -p "Process name? " proc;; *) proc=$1;; esac
# Maybe your ps aux doesn't have the command in $11 -- adapt
kill $(ps aux -O start |
awk -v name="$proc" 'NR>1 && tolower($11) ~ tolower(name) {print $2}')
Your comments indicate you seek to kill the "latest" process (by which metric?) but your code, and this code, attempts to kill all the instances. If you want the most recently started process, the PID is not a good indicator; you should look at process start times etc. The output of ps
is heavily system-dependent so you should probably post a separate question with more details about your OS if you need help figuring that out.
This particular problem regularly gets beaten to death several times a month here, so you should probably look at other implementations for inspiration. My recommendation would be "don't do that" but since you already did, I suppose it makes sense to point out the flaws and attempt to solidify the code. But if you don't have a compelling reason why you cannot install pkill
, you should probably just use that (and if you do, using a properly debugged and tested script is way better than writing your own from scratch).
Upvotes: 1
Reputation:
You could just use awk alone with getline to call out to ps and get the data you want:
awk -vv_kp="bash" 'BEGIN{ cmd="ps -axu -O T | grep "v_kp" |head -1"; cmd | getline var; close(cmd); split(var,var2," ");print var2[2];}'
or less awk, more shell:
awk -vv_kp="bash" 'BEGIN{ cmd="ps -axu -O T | grep "v_kp" |head -1|cut -d\" \" -f2"; cmd | getline var; close(cmd); print var;}'
Upvotes: 0