The macosxhints Forums

The macosxhints Forums (http://hintsforums.macworld.com/index.php)
-   UNIX - General (http://hintsforums.macworld.com/forumdisplay.php?f=16)
-   -   AppleScript/shell script doo-dad here... (http://hintsforums.macworld.com/showthread.php?t=698)

rusto 02-05-2002 06:25 PM

AppleScript/shell script doo-dad here...
 
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).

Code:

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 06: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 07:10 PM

I've not run it as an app...give it a try with Script Runner.

xchanyazy 02-05-2002 07: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 07: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 07: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 08:10 PM

Quote:

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 08:22 PM

Here is the code I am using..
Code:

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,
Code:

ps ax | grep -i dnetc | grep -vc grep
returns the correct variable.

EDIT: Realized I had typed something wrong...

mervTormel 02-05-2002 08: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 08:39 PM

Code:

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 09: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 10: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 10: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:

Code:

        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":

Code:

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:

Code:

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 11: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-06-2002 12:20 AM

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 02: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 02: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 02: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?
Code:

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 02: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 09: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.

Quote:

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)


All times are GMT -5. The time now is 05:45 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.