View Full Version : AppleScript/shell script doo-dad here...
rusto
02-05-2002, 05:25 PM
I got sick of having to launch the terminal to toggle a particular background app that I use on and off so after some research (mervTormel would be pleased) and fiddling around I came up with the following AppleScript that calls some shell scripts along the way.
Cut/paste the code into the Script Editor, to customize it for your purposes just change the code in the where indicated by the comments. You can save it as an app or save as compiled script and run it from the Script Runner, ScriptMenu or Dragthing (DT lets you set hot keys to launch).
on run
-- change the text "appName" below to name of your application
do shell script "outPut=`ps ax | grep -i \"appName\" | grep -vc grep`;echo $outPut"
set isItOn to the result
if isItOn = "1" then
-- don't forget to change the text in the dialogs to suit!
display dialog "appName is on, would you like to turn it off?" buttons {"No", "Shut off"} with icon stop default button 1
if the button returned of the result is "Shut off" then
-- change the text "appName" below to name of your application
do shell script "kill -15 `ps ax | grep -i \"appName\" | grep -v grep | cut -c 1-6`"
end if
else
display dialog "appName is off, would you like to turn it on?" buttons {"No", "Start"} with icon caution default button 2
if the button returned of the result is "Start" then
-- set path to application and launch command below
do shell script "cd /path/to/app/;./appName"
end if
end if
end run
xchanyazy
02-05-2002, 05:57 PM
This worked well for me in the ScriptEditor (by pressing run), however, when I saved it as an application, it always tells me that the application is on, even when it's not. Any ideas as to why that would be?
Used the script for the distributed.net client.
rusto
02-05-2002, 06:10 PM
I've not run it as an app...give it a try with Script Runner.
xchanyazy
02-05-2002, 06:21 PM
Yep, that worked fine (plus, now it's in my script menu). However, I'm still kind of curious, why wouldn't the application work the same?
BTW, thanks for the script, a great idea.
rusto
02-05-2002, 06:32 PM
The only thing I can think of is that the "do shell script..." portions might not be compiled the same way as the script is saved as an application.
mervTormel
02-05-2002, 06:56 PM
excellent. i am, indeed, pleased.
ps ax truncates the output to your terminal width
you might want to use ps axww when grep'n to get the whole enchilada in case your command path is long long and the real command is hangin' way way out there. one w gets you 132 columns, the second w gets you all of the command line
% ps ax | grep rage
21282 ?? S 4:47.38 /Volumes/chunder/xapps/Microsoft Office X/Microsoft Entourage /Volumes/chunder/xapps/Microsoft Office X <-truncated to terminial column width
27438 std R+ 0:00.01 grep -i rage
% ps axww | grep rage
21282 ?? S 4:47.41 /Volumes/chunder/xapps/Microsoft Office X/Microsoft Entourage /Volumes/chunder/xapps/Microsoft Office X/Microsoft Entourage -psn_0_25165825
27442 std R+ 0:00.01 grep -i rage
and your grep -vc may return a false false? which = true
anyhow, grep pipe grep -v is heinous.
instead, try:
| grep -i "[a]ppname"
% ps axww | grep -i "[e]ntourage"
21282 ?? S 4:53.79 /Volumes/chunder/xapps/Microsoft Office X/Microsoft Entourage /Volumes/chunder/xapps/Microsoft Office X/Microsoft Entourage -psn_0_25165825
here, grep doesn't find itself
-i for ignore case, the brackets cause a regexp that is always found, but the grep for it isn't found because it contains the [] in the command, or something. play with it.
mervTormel
02-05-2002, 07:10 PM
Originally posted by xchanyazy
This worked well for me in the ScriptEditor (by pressing run), however, when I saved it as an application, it always tells me that the application is on, even when it's not. Any ideas as to why that would be?
Used the script for the distributed.net client.
this is odd and needs to be investigated, so start by breaking the script down
i would be interested to see the results of your ps ax | grep from your terminal window. try and make it the same test that failed.
xchanyazy
02-05-2002, 07:22 PM
Here is the code I am using..on run
do shell script "outPut=`ps ax | grep -i \"dnetc\" | grep -vc grep`;echo $outPut"
set isItOn to the result
if isItOn = "1" then
display dialog "dnetc is on, would you like to turn it off?" buttons {"No", "Shut off"} with icon stop default button 1
if the button returned of the result is "Shut off" then
do shell script "kill -15 `ps ax | grep -i \"dnetc\" | grep -v grep | cut -c 1-6`"
end if
else
display dialog "dnetc is off, would you like to turn it on?" buttons {"No", "Start"} with icon caution default button 2
if the button returned of the result is "Start" then
do shell script "/Applications/Math/dnetc-macosx-ppc/dnetc"
end if
end if
end run
When run from terminal, ps ax | grep -i dnetc | grep -vc grep returns the correct variable.
EDIT: Realized I had typed something wrong...
mervTormel
02-05-2002, 07:31 PM
xchanyazy,
for the terminal run, get those escaped quotes out of there, and leave off the grep -v
we're testing and we need to see the results of the atomic components of the command line
in the script, how about making appName a variable so you only have to change it one place, rather than a literal string?
xchanyazy
02-05-2002, 07:39 PM
ps ax | grep -i dnetc
666 ?? RN 4:56.66 /Applications/Math/dnetc-macosx-ppc/dnetc
705 std U+ 0:00.00 grep -i dnetc
I tried getting rid of the quotation marks, but it had no effect on the application working. It still always thought the process was not running. The script still worked just fine without them, though.
mervTormel
02-05-2002, 08:28 PM
sorry, gentlemen, i no habla applescript too very good, and i see my suggestions have made the ascript part much harder, but that's all part of programming robust systems ;] and *sigh*
'do shell script' is run with the sh shell (bourne shell), which we no got, so i think it runs under zsh, which has different quoting syntax ?
of course, your script will fail if your appname is foobar and there is also a process with foobarblatz in its path. you may need to use basename to get the canonical name of the app in the process matched up with the appName literal (or value of the appName variable) details, details, details. this is the time many hearty souls go watch tv =;]
% basename /Applications/TextEdit.app/
TextEdit.app
anyhow, xchanyazy, see if this works consistantly with grep'n your dnetc...
set grepName to "[t]extedit"
set appName to "TextEdit"
do shell script "outPut=`ps axww | grep -ic " & grepName & "` ; echo $outPut"
rusto
02-05-2002, 09:11 PM
Haven't had time to do any testing myself but will confirm the 'do shell script' runs with sh...I've been testing it OK in the terminal cuz I'm using the bash shell.
And yes, the \ in Apple script are escapes that should be dropped to try the shell script portions in sh or bash.
Can't wait till tomorrow to fiddle about some more!
rusto
02-05-2002, 09:47 PM
Ah, it takes but a moment for inspiration and insight...I really don't care if my grep finds itself: I just changed the test, that's all.
I changed this, where I made grep "remove" itself from the result:
do shell script "outPut=`ps ax | grep -i \"appName\" | grep -vc grep`;echo $outPut"
set isItOn to the result
if isItOn = "1" then
to this, where grep will find appName (if it's runing) and itself, I just test for a "2":
do shell script "outPut=`ps axww | grep -ic \"appName\"`;echo $outPut"
set isItOn to the result
if isItOn = "2" then
so the total script looks like this now:
on run
-- change the text "appName" below to name of your application
do shell script "outPut=`ps axww | grep -ic \"appName\"`;echo $outPut"
set isItOn to the result
if isItOn = "2" then
-- don't forget to change the text in the dialogs to suit!
display dialog "appName is on, would you like to turn it off?" buttons {"No", "Shut off"} with icon stop default button 1
if the button returned of the result is "Shut off" then
-- change the text "appName" below to name of your application
do shell script "kill -15 `ps ax | grep -i \"appName\" | grep -v grep | cut -c 1-6`"
end if
else
display dialog "appName is off, would you like to turn it on?" buttons {"No", "Start"} with icon caution default button 2
if the button returned of the result is "Start" then
-- set path to application and launch command below
do shell script "cd /path/to/app/;./appName"
end if
end if
end run
mervTormel
02-05-2002, 10:07 PM
gentlemen,
this is my swipe at it.
http://home.mindspring.com/~bduart/toggleApp.scr.sit
only one ps | grep | awk to get the pid, if the pid is null, ask to launch it, if the pid is not null, ask to kill it
now, the trick is to only have to define appName="theAppName" and to programmatically create the grepName
how
lowercase the value of appName
stuff a ] after the first char and a [ before the first char
can applescript do this kinda stuff?
xchanyazy
02-05-2002, 11:20 PM
mervT,
Tried your script, and it seemed to work, except that you can't open dnetc with "open -a", I just removed that and used just the appName variable (which I declared as the path to the application). Also, still didn't work when saved as an Application. It could launch the process, but not kill it. (also had to change kill -15 to kill, as kill -15 didn't terminate the process).
Also, after running the application version of your script (modified as above), a process called "find" was taking up ~30% of my CPU, and I had to sudo kill it. I believe it was connected to the app from your script, as I was not able to delete it (finder said it was in use) until I killed the find process.
I need to study for a german quiz, but I'll look around for some answers tomorrow..
pmccann
02-06-2002, 01:12 AM
Yep, if you don't mind a touch of ugliness... but then string processing in applescript is irreducibly ugly.
set stuff to "someword"
set stuffed to "[" & character 1 of stuff & "]" & characters 2 thru -1 of stuff
Looks 'orrible but should work OK as long as what's in stuff is longer than 2 characters. I guess an "if" would be prudent here:
set stuff to "b"
if (length of stuff > 1) then
set stuffed to "[" & character 1 of stuff & "]" & characters 2 thru -1 of stuff
else if (length of stuff = 1) then
set stuffed to "[" & stuff & "]"
end if
return stuffed
I don't doubt there are better ways to do it: the phrase "rest of" keeps popping into my mind, but my applescript days are long behind me. Aah, rest of is for lists: could break the string up and deal with list of chars, but it's probably overkill here. Maybe something prettier will crystallise later on.
((In perl:
$stuff=~s/^(.)/\[$1\]/
or something I find amusing in its perversity:
substr($stuff,0,1)="[".substr($stuff,0,1)."]";
))
Cheers,
Paul
still hobbled by last night's daemonic possession
pmccann
02-06-2002, 01:38 AM
OK, I should be a little fairer to applescript: its string processing capabilities are not great, but they're better than the snippet I listed above. A little more creativity has yielded a couple of neater alternatives: first one's marginally better...
set b to "some text"
set c to text items of b
set item 1 of c to "[" & item 1 of c & "]"
set myoutput to c as text
and the second one is pretty much what I was groping for when constructing the previous message...
set b to "some text"
set myoutput to "[" & text item 1 of b & "]" & rest of (text items of b)
That'll do in any case: I can now rest more easily!
Cheers,
Paul
mervTormel
02-06-2002, 01:42 AM
xchanyazy,
regrets, as i alluded, these things need to be very robust. i find that most progamming is error handling and reducing to subatomic particles, the problem, and reconstructing it piece by piece, considering all the possibilities, then dealing with the last one hundred gotchas as other users mash into it.
even tho i tried to do no harm, it's always a good idea to eyeball code pretty good to see that it's kosher. kill -15 should not be a cavalier expression.
paul,
ugly is truly in the eye of the beholder. does anyone besides me and Grace Mary Hopper think applescript looks like cobol? yish. and that perl $stuff ?! you mean i can program in perl if i just let my cat walk across the keyboard?
that last substr bit reminds me of my lineage, which i'm embarrassed to mention, but now has to become a trivia question. we used to parse and create strings that very $stuff way. in fact, perusing the Perl manual, i saw many ideas born from this ANSI language.
what language?
x="thisldo"
x=$e(1,5,x)_"hafta"_$e(6,999,x)
w x
thislhaftado
i doubt google will help you here.
mervTormel
02-06-2002, 01:58 AM
paul, are we keeping you up? much gratitude for your code snippets and otherwise always erudite contributions. regards, -mt
pmccann
02-06-2002, 08:56 AM
What's that? Keeping me up? Oh yes; but my presence this forum has the side benefit of keeping me from a very-hard-to-finish series of posts elsewhere. *M-u--s----t f-i--n---i----s-----h....*
I tried to track down your language snippet, but emerged with empty hands.
When I started designing Perl, I explicitly set out to deconstruct all the computer languages I knew and recombine or reconstruct them in a different way, because there were many things I liked about other languages, and many things I disliked. I lovingly reused features from many languages. (I suppose a Modernist would say I stole the features, since Modernists are hung up about originality.) Whatever the verb you choose, I've done it over the course of the years from C, sh, csh, grep, sed, awk, Fortran, COBOL, PL/I, BASIC-PLUS, SNOBOL, Lisp, Ada, C++, and Python. To name a few. To the extent that Perl rules rather than sucks, it's because the various features of these languages ruled rather than sucked.
Alas, Alack, ALarry, none of those Monikers seems to fit this particular Bill. The language seems to have gone AWall.
That is, I give up!
Paul (relatively new to this game, and thus remarkably poorly endowed with computing folklore)
mervTormel
02-06-2002, 01:06 PM
s d1="/"
r "enter acct num: ",r
s s=^acct(r,1) ; <- access the acct database for acct number r
w s
"name/address/city/state/zip/phone"
f n=1:1:$p(s,d1,n)="" w $p(s,d1,n),!
name
address
city
state
zip
phone
----
One of the first ANSI languages was MUMPS (Massachusetts General Hospital Utility Multi-Programming System). Invented by Dr. G. Octo Barnett and Neil Papallardo, on DEC PDP-7, with 8K of core memory, in 1966. (Set the way-back machine, Mr. Peabody. -Sherm)
http://cgibin.erols.com/ziring/cgi-bin/cep/cep.pl?_key=MUMPS
Unfortunately, it's name invokes the thought of a childhood disease that causes sterility, and it's market has always been hampered by that. They tried to rename it in the 80's, and suggestions were always of the same ilk: "Cancer," "Leprosy," "Measles." ;[
A quirky little language, but one could write an awful lot of productive code very quickly.
(Shut up, you! -Mr. Peabody)
rusto
02-06-2002, 02:06 PM
Phew merv, you got your answer in there just before I (wrongly) guessed it was APL...which was the first computer language I learned (well, learned doesn't really count if you don't remember anymore) in 1978.
pmccann
02-07-2002, 09:38 AM
Hi mT,
I wouldn't have "got" MUMPS in a million years of searching!
I can see the attraction of the language from your sample (much more so than from the sample code in the link you provided; the latter did, however, prove interesting reading). Very nice, very niche, but not very Nietzsche. Working with strings and only strings must have proved fun for some tasks!
Just had a quick poke around google: poor old MUMPS, the attempted makeovers are a little sad. Most of the sites are enthusiastic, but feel a little like ghost towns. And as for "The MUMPS User's Group is known as the M Technology Association", the less said the better! Makes me think of bad sci-fi, or bad music (M People?), or some sort of New Age Healing. Several significant nice one letter languages that I'm familiar with: B,C,R,S, (sorta X), so no problem there: must be the "Technology" side of things that adds an air of desperation.
Cheers,
Paul
meancode
02-25-2002, 06:44 AM
would it be easier to do this:
i use this to start and kill Classic:
tell application "Finder"
if (name of (every application process)) contains "Classic Support" then
activate
display dialog "Classic is running, want to quit it?" buttons {"Not now", "Sure do"} default button "Sure do"
set the user_choice to the button returned of the result
if the user_choice is "Sure do" then
tell application "Classic Support" to quit
end if
else
activate
display dialog "Classic is not running, want to start it?" buttons {"Not now", "Sure do"} default button "Sure do"
set the user_choice to the button returned of the result
if the user_choice is "Sure do" then
tell application "Classic Startup"
activate
end tell
end if
end if
end tell
rusto
02-25-2002, 08:33 AM
Can't get that script to compile because the Script Editor is looking for "Classic Support" and "Classic Support" cannot be viewed by the editor's "Choose Application" dialog box.
Besides, it would not work for an application that can only be launched from the command line which was the point of the exercise.
vBulletin® v3.8.7, Copyright ©2000-2013, vBulletin Solutions, Inc.