killing multiple processes, awk

Im trying to modify a script I’ve found http://macstuff.beachdogs.org/blog/?p=31 that kills off a process via its name. It works very well in most instances. The problem Im having is that the shell sometimes returns multiple values (child processes) and sometimes there is more then one process with a name.

set processes to (do shell script "ps ax | grep " & (quoted form of app_name) & " | grep -v grep | awk '{ print $1}'")

This portion of the script lists the process with a return but if Im going to use them in an apple script they should be quoted and comma seperateed no?

At present the output looks like:

(*51587
51591
51604*)

This is where im trying to get to: Killing each process one at a time until there are no more.

set app_name to "ImagePrint"
set processes to (do shell script "ps ax | grep " & (quoted form of app_name) & " | grep -v grep | awk '{ printf $1}'") as list
repeat with the_pid in processes
try
	log the_pid
	if the_pid is not "" then do shell script ("kill -9 " & the_pid)
	end try
end repeat

I know the problem is with awk, but I just cant seem to configure it so that the returns are striped, spaces and quotes and commas added. I believe these are needed to be processed as a list.

Thanks for checking this out.
Ben

Hi

I don’t think this is what you’re looking for, but here’s an app I use in the dock to quit most of the visible processes:

[applescript
tell application “System Events”
set app_list to (name of every process whose visible is true and name is not “QuitApps” and name is not “Finder”)
end tell
repeat with this_app in app_list
tell application this_app to quit
end repeat
]



It works most of the time, but once in a while it doesn't quit some visible processes. I think maybe they're still busy.

gl,

Hey Ben,

This is a trifle round-about, but it works:


do shell script "
KILL_LIST=`ps -axc -o pid,comm | egrep -i \"viewit|leech|rpn.*sci|textedit\" | sed -En 's!^ *([0-9]+).+!\\1!p' | awk 'BEGIN{ ORS=\" \"; } { print $1 }'`
kill $KILL_LIST
"

If you’re on Mountain Lion (and maybe Lion) there’s also pgrep & pkill, although you might have to install Xcode and its command-line-tools (I’m not sure and can’t easily check).

pgrep -i “viewit|leech|rpn.*sci|textedit”
pkill -i “viewit|leech|rpn.*sci|textedit”

You can to more with AWK than just printing fields :wink:

set processName to "http"
do shell script "ps -Ac -o pid,comm | awk '/^[[:space:]]*[[:digit:]]*[[:space:]]" & processName & "$/{
if (length(pid) != 0)
	printf pid\", \"
pid = $1} END {printf pid}'"

I’m using a more precise regular expression with AWK because when you have two processes like iTunes and iTunes Helper your script will kill both when you want to kill iTunes only.

Edit: adding spaces and commas can also easily done by using text item delimiters:

set processName to "httpd"
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ", "}
set thePIDs to every paragraph of (do shell script "ps -Ac -o pid,comm | awk '/^[[:space:]]*[[:digit:]]*[[:space:]]" & processName & "$/{print $1}'") as string
set AppleScript's text item delimiters to oldTID
return thePIDs

Hello.

Here is something I used to use, but from a terminal window, it willl ask you about the processes that match your pattern, until you you have answered for each and every one.

Maybe you can rework this functionality into AS. I have been working now and then on a c version, that lists all processes, and lets you kill the one that matches a pattern interactively. I haven’t make it use reg-exe’s yet, so it gives too much back to be useful.

Here is yesno, that queries you for y or n:

[code]#! /bin/bash

### CMD Returns exitcode upon pressing y or n or q, “keypress” read code. !#

Traps ^C to keep our terminal sane under all conditions. Q - quits.

Conventions:

Under no circumstanses will the user have the possibiltiy to interrupt us by pressing ^C

Pressing ^Z on the other hand, is really a feature should the user want to inspect something

before he answer.

Then it is nice to see the previous question again after she presumably have

inspected what she was to do with the item in question.

This is the convention. Its easy to add features like All, by adding some functionality.

trap ‘’ SIGTSTP

trap - SIGTSTP

prgname=yesno
version=“1.0”
Usage=“Usage : $prgname [-huv; --help, --usage, --version ]”
version()
{
echo $prgname" : “$version”
Copyright 2008 (c) Tommy Bollman
Is put in the public domain under the GNU Gpl 2.0 license.
No warranties about what so ever are given about what so ever

  • to the extent permitted by law.
    $prgname Needs the Bash commandline interpreter in order to work."
    tommybollman@mac.com
    }
    phelp()
    {
    echo "
    $Usage
    $prgname : filters the keyboard for the keypresses: [yY] [nN] [qQ] and returns a corresponding
    exitcode
    lets Suspend interrupts (^Z) fall through and gives an unique returncode when awakes again.
    Read the manpage (yesno.1) or read the program code ($0) for information.
    INTENT
    $prgname : Enables swift responses from the user to the utility, and gives the caller an
    opportunity to rerun any questions if the calling process was suspended. Like if the user has
    suspended the program to find out if it is really sound to overwrite that file after all.
    " 1>&2
    }
    myhandler()
    {
    trap ‘’ SIGCONT
    echo “interrupted!!!”
    exit 101
    }
    if [ $# -gt 0 ] ; then
    if [ $# = 1 ] ; then
    if [ “$1” = “-u” -o “$1” = “-h” -o “$1” = “–help” -o “$1” = “–usage” ] ; then
    phelp ; exit
    elif [ “$1” = “-v” -o “$1” = “–version” ] ; then
    version ; exit
    else
    echo "Bad option $1 " 1>&2
    echo $Usage 1>&2
    exit
    fi
    else
    echo "Bad nr of arguments " 1>&2
    echo $Usage 1>&2
    exit
    fi
    fi
    trap ‘’ SIGINT
    trap myhandler SIGCONT
    while true; do {

ehco here

read -n 1 -s MYCHAR </dev/tty
case "$MYCHAR" in
([yY])
	 exit 0 ;;
([nN])
	 exit 1 ;;
([qQ])
	 exit 99 ;;
esac

} done[/code]
Here is pick, that returns the answers from a query.

[code]#! /bin/bash

### pick: select arguments

declare ret
for i # for each argument
do
echo -n " “$(echo $i |sed -n ‘s/[ ]*$//p’)”:(y/n/q)?" >/dev/tty
yesno
if ret=$? ; [ $ret -eq 0 ] ; then
echo “$i”
echo " – Yes" >/dev/tty
elif [ $ret -eq 99 ] ; then
echo " – Quit" >/dev/tty
exit 1
else
echo " – No" >/dev/tty
fi
done </dev/tty[/code]
here is zap, that kills processes interactively.

[code]#!/bin/bash

zap pat: kill all processes matching pat

final version

exercise version: shows the heading of the ps command as it is.

PATH=/bin:/usr/bin:~/bin
IFS=’
’ # just a newline
case $1 in
“”) echo ‘Usage: zap [-0…15] pattern’ 1>&2; exit 1 ;;
-) SIG=$1; shift
esac
program_arguments_missing=$

processes=${program_arguments_missing:?Usage: zap [-0…15] process name 1 process name 2 …}
processes=$( echo $processes PID )
wantedprocesses=echo $processes |sed 's/ /|/g'
#must really make a temp file here, to keep the process info.
TMPFILE1=/tmp/zap$$
TMPFILE2=/tmp/zap2$$
ps -ax |egrep $wantedprocesses |sed ‘/zap/ d’ >|$TMPFILE1
head -1 <$TMPFILE1 >/dev/tty
sed -e 1d -e ‘/egrep.*PID/ d’ <$TMPFILE1 >|$TMPFILE2
kill $SIG pick \cat $TMPFILE2 ` | awk ‘{print $1}’` 2>/dev/null[/code]
Both zap and pick are from the book: The Unix Programming Environment.

Edit
Most of the time, I kill processes with Activity monitor, but when I’m in doubt about the command line arguments, and there are multiple processess with a tool involved, then I have to resort to the commandline. Most of the time, Activity Monitor does a good job, as I can search for the process-name in the search field, and there are numerous ways to sort the view too, so I can look for processes by name, or cpu-usage for instance.

Edit+
I played a little with the now obsolete zap script, and I changed it to not include zap itself.

All those three scripts are surmised to reside in a ~/bin folder.

Well - Im totally floored folks. What an amazing response! It going to take a while to process all of the responses and see what’s most appropriate ““ but a a big thank-you to everyone that’s posted.

Ben