4
4

3 回答 3

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}
于 2012-09-02T13:05:48.657 回答
2

use xargs:

ps aux | grep -ie perl | awk '{print $2}' | xargs kill -9 
于 2014-01-09T21:53:29.833 回答
1

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
于 2012-09-02T11:11:21.117 回答