I\'m trying to write a bash script to find the PID of a running process then issue a kill command. I have it partially working, but the issue I face is that there may be mor
Don't know why you would ever grep for a process to kill, unless you didn't know the command name. Most modern versions of ps have the flags
-C cmdlist
Select by command name. This selects the processes whose executable name is given in cmdlist.
and
-o format
User-defined format. format is a single argument in the form of
a blank-separated or comma-separated list, which offers a way to
specify individual output columns. The recognized keywords are
described in the STANDARD FORMAT SPECIFIERS section below.
Headers may be renamed (ps -o pid,ruser=RealUser -o
comm=Command) as desired. If all column headers are empty (ps
-o pid= -o comm=) then the header line will not be output.
Column width will increase as needed for wide headers; this may
be used to widen up columns such as WCHAN (ps -o pid,wchan=WIDE-
WCHAN-COLUMN -o comm). Explicit width control (ps opid,
wchan:42,cmd) is offered too. The behavior of ps -o pid=X,
comm=Y varies with personality; output may be one column named
"X,comm=Y" or two columns named "X" and "Y". Use multiple -o
options when in doubt. Use the PS_FORMAT environment variable
to specify a default as desired; DefSysV and DefBSD are macros
that may be used to choose the default UNIX or BSD columns.
So you can just do
ps -o pid= -C commandName
Will return the pid of all processes named exactly commandName and is cleaner and faster. Or kill a loop
while read -r pid; do
kill "$pid"
done < <(ps -o pid= -C commandName)
But really, you should always just be able to do
> pkill commandName
You don't need to use an array if you're going to immediately iterate over the results and perform an action:
for pid in $(ps -fe | grep '[p]rocess' | grep -v grep | awk '{print $2}'); do
kill "$pid"
done
Notice we have to exclude grep
's pid from the list of processes to kill. Or we could just use pgrep(1)
:
for pid in $(pgrep '[p]rocess'); do
kill "$pid"
done
If you actually needed to store the pids in an array, pgrep
is how you would do it:
pids=( $(pgrep '[p]rocess') )
Back to killing process. We can still do better. If we're just using pgrep
to get a list of processes to kill them, why not go straight for pgrep
's sister program: pkill(1)
?
pkill '[p]rocess'
As it turns out, no need for bash
scripting at all.
Your script seems fine, if you want to have each pid list on a new like then replace:
echo $pid
#kill $pid
with
echo "$pid"
#kill "$pid"
Here's a little one liner that might help
for pid in `ps -ef | grep your_search_term | awk '{print $2}'` ; do kill $pid ; done
Just replace your_search_term with the process name you want to kill.
You could also make it into a script and swap your_search_term for $1
EDIT: I suppose I should explain how this works.
The back ticks `` collects the output from the expression inside it. In this case it will return a list of pids for a process name.
Using a for loop we can iterate through each pid and kill the process.
EDIT2: replaced kill -9 with kill