3 回答
For maximum portability and reliability, use -A
(POSIX synonym of -e
) and a custom format with -o
rather than -f
.
Your filtering of the output of ps
is brittle: it may match other processes. You've had to exclude the grep process, and you may need to exclude your script as well, and there may be other completely innocent processes caught in the fray (such as your script itself) because their command line happens to contain $process
as a substring. Make your filtering as strict as possible. With ps -o pid= -o comm=
, you get just two columns (PID and command without arguments) with no header.
You don't need to use a loop to do the killing, kill
accepts multiple arguments. For the counting, let the shell do it: you have a whitespace-separated list of numbers, to let the shell do the word splitting (with $(…)
outside quotes) and count the number of resulting words ($#
).
count_and_kill_processes () {
set -- $(ps -A -o pid= -o comm= |
awk -v "name=$process" '$2 == name {print $1}')
count=$#
if [ $# -ne 0 ]; then kill "$@"; fi
}
count_and_kill_processes foo
# now the number of killed processes is in $count
If your shell is bash or ksh on all machines, you can use an array.
pids=($(ps -A -o pid= -o comm= |
awk -v "name=$process" '$2 == name {print $1}') )
if [[ $# -ne 0 ]]; then kill "$@"; fi
# the number of killed processes is ${#pids}
use xargs:
ps aux | grep -ie perl | awk '{print $2}' | xargs kill -9
You can use a loop which should work in both cases:
for pid in $(ps -ef | grep -v grep | grep $process | awk '{print $2}'); do
echo $pid
done
Or count the number of matches:
if [ $(ps -ef | grep -v grep | grep $process | awk '{print $2}' | wc -l) -gt 1 ]
then
# more than one
fi