Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > macOS > Running Shell Scripts 101 - Help!

Running Shell Scripts 101 - Help!
Thread Tools
mokolabs
Fresh-Faced Recruit
Join Date: Jul 2001
Location: New York NY
Status: Offline
Reply With Quote
May 2, 2003, 01:28 PM
 
Ok, you wouldn't think this is rocket science, but apparently it is.

I've written a shell script...

#!/bin/sh

# Kill any Summary-related processes
ps -ax | grep Summary | grep -v grep | awk '{print $1}' | xargs kill -9

# Relaunch
open "/Applications/Summary 2.0.5/Summary 2.0.5"
How can I...

(A) Run it from the Terminal?
(B) Run it with Cron?

(I've got Cronnix -- just need to know the actual command I need to execute the script).

Thanks!

Patrick
     
utidjian
Senior User
Join Date: Jan 2001
Location: Mahwah, NJ USA
Status: Offline
Reply With Quote
May 2, 2003, 01:58 PM
 
Originally posted by mokolabs:
Ok, you wouldn't think this is rocket science, but apparently it is.

I've written a shell script...



How can I...

(A) Run it from the Terminal?
(B) Run it with Cron?

(I've got Cronnix -- just need to know the actual command I need to execute the script).

(A) Assuming you named it something kike "mykillerscript.sh" is should be as easy as:

sh mykillerscript.sh

(B) Dunno about Cronnix. For regular cron take a look at the entries in /etc/crontab should give you enough examples and also look at the manpage.
-DU-...etc...
     
gatorparrots
Dedicated MacNNer
Join Date: Dec 2002
Location: someplace
Status: Offline
Reply With Quote
May 2, 2003, 04:25 PM
 
Originally posted by mokolabs:
I've written a shell script...
#!/bin/sh

# Kill any Summary-related processes
ps -ax | grep Summary | grep -v grep | awk '{print $1}' | xargs kill -9

# Relaunch
open "/Applications/Summary 2.0.5/Summary 2.0.5"

I would make the kill argument more efficient:
kill `ps auxc | grep Summary | awk '{print $2}'`

Or killall may even do what you want:
killall -m Summary
( Last edited by gatorparrots; May 2, 2003 at 04:31 PM. )
     
mokolabs  (op)
Fresh-Faced Recruit
Join Date: Jul 2001
Location: New York NY
Status: Offline
Reply With Quote
May 2, 2003, 05:29 PM
 
This turned out to be the script from hell.

Since Summary is a carbon app, it doesn't respond to "open" -- you have to pass everything through LaunchCFMApp, like this...

/System/Library/Frameworks/Carbon.framework/Versions/Current/Support/LaunchCFMApp '/Applications/Summary 2.0.5/Summary 2.0.5'

But, once you've launched Summary, you lose the unique process name (which the grep in the first part of the script was looking for) -- and get a generic 'LaunchCFMApp' instead.

So, you can kill it -- but it will take down all other Carbon apps, like, um, BBEdit.

...

I wanted to be a Unix god, but it just didn't work out -- so I wound up using AppleScript instead.

You can save this script to your desktop, and run it straight from the terminal (or any cron script) just by typing "~/Desktop/Script.app" or "open '~/Desktop/Script.app'".

-- Quit Summary
tell application "Summary 2.0.5"
quit
end tell

-- Wait for Summary to Quit
repeat with j from 1 to 1000000
end repeat

-- Launch Summary
tell application "Summary 2.0.5"
activate
end tell

...

I'd still love to know how to do all of this using a shell script, if anyone knows.
     
Rainy Day
Grizzled Veteran
Join Date: Nov 2001
Location: Oregon
Status: Offline
Reply With Quote
May 3, 2003, 11:46 AM
 
In this particular instance, i should think your AppleScript approach is better than a shell script, given that you're dealing with a carbon app. A "quit" AppleEvent is graceful, whereas a shell "kill -9" is not.

-- Wait for Summary to Quit
repeat with j from 1 to 1000000
end repeat
Here's your chance to become a UNIX god: Use the vastly more efficient UNIX sleep command for your delay:

  do shell script "sleep 10"

The sleep command's parameter is expressed in seconds, so the above command will delay 10 seconds.

Of course an AppleScripter might be tempted to use a loop like repeat while (the process theApp exists) in their script, combining that with a short UNIX sleep command inside the loop. (They would be wise, however, to limit the time spent in the loop, or the number of iterations, to avoid infinite loops in the event the app decides not to quit.)
     
Gary Kerbaugh
Dedicated MacNNer
Join Date: Jul 2001
Location: NC
Status: Offline
Reply With Quote
May 3, 2003, 02:09 PM
 
Originally posted by mokolabs:
-- Wait for Summary to Quit
repeat with j from 1 to 1000000
end repeat
   Actually AppleScript has a "delay" function that behaves like the shell's sleep function. A variant of Rainy Day's example would be to define a function like: (from Apple's GUI Scripting examples)

on wait4process(this_process)
   tell application "System Events"
      repeat with i from 1 to 60
        &n bsp;if not (the process this_process exists) then return true
        &n bsp;delay 1
      end repeat
   end tell
   return false
end wait4process
Gary
A computer scientist is someone who, when told to "Go to Hell", sees the
"go to", rather than the destination, as harmful.
     
mokolabs  (op)
Fresh-Faced Recruit
Join Date: Jul 2001
Location: New York NY
Status: Offline
Reply With Quote
May 3, 2003, 03:55 PM
 
I tried using your code, RainyDay, but when I do, the 3rd step (restarting Summary) fails.

It generates a 'Connection is invalid' error.
     
mokolabs  (op)
Fresh-Faced Recruit
Join Date: Jul 2001
Location: New York NY
Status: Offline
Reply With Quote
May 3, 2003, 04:10 PM
 
Apparently, that error message is generated when a process is still busy or unavailable. So, I'm guessing that the quit, despite the 10 second pause, still isn't complete -- so it interferes with the relaunch bit.

I wound up using the delay command, which works better for some reason.

-- Quit Summary
tell application "Summary 2.3.3"
quit
end tell

-- Wait for Summary to Quit
delay 5

-- Launch Summary
tell application "Summary 2.3.3"
activate
end tell
     
Rainy Day
Grizzled Veteran
Join Date: Nov 2001
Location: Oregon
Status: Offline
Reply With Quote
May 3, 2003, 04:40 PM
 
Actually AppleScript has a "delay" function that behaves like the shell's sleep function.
Yes, but delay chews up (i.e. wastes) CPU cycles, whereas sleep does not. This is actually what i meant when i said "vastly more efficient" (although i see, in retrospect, the reader might think i had meant "was more efficient that a simple counting loop").

So, I'm guessing that the quit, despite the 10 second pause, still isn't complete -- so it interferes with the relaunch bit.
10 seconds was merely pulled out of thin air. I have no idea how long your counting loop delay took (it would vary depending on the speed of your Mac). But this problem which you mention is exactly why i suggested a repeat while (the process theApp exists) loop. You really don't know how long it might take an app to quit, so looking to see if it's still active is the best approach. Sticking a sleep in the middle of the loop ensures the loop itself doesn't chew up CPU cycles (testing to see if the app has quit). If this is a background script, a three second (or even longer) sleep might be a good choice. If the user is waiting for the script to finish, i'd use a one second sleep.

But as i said previously, you also need to make sure you don't wait around forever, in case the app doesn't quit, so add a second condition to the loop (e.g. something which checks the elapsed time, or something which counts passes through the loop).

Edit:
A computer scientist is someone who, when told to "Go to Hell", sees the "go to", rather than the destination, as harmful.
Are you insinuating the goto isn't harmful?
( Last edited by Rainy Day; May 3, 2003 at 04:48 PM. )
     
mokolabs  (op)
Fresh-Faced Recruit
Join Date: Jul 2001
Location: New York NY
Status: Offline
Reply With Quote
May 3, 2003, 04:51 PM
 
To clarify -- the Summary application actually quits instantly (from a user's perspective, anyway). But the quit process keeps the app busy for some reason, so a delay is needed before any relaunch attempt.

If I was worried about CPU cycles, or excessively delayed quit times, I would definitely go with the other approaches suggested.

But, since this box is only doing one thing (running Summary) and the app always quits promptly, I'll just use 'delay' for now.

I'll see how it goes, though -- maybe I'll need to utilize these other solutions down the road.

Thanks for your help, guys!
     
mokolabs  (op)
Fresh-Faced Recruit
Join Date: Jul 2001
Location: New York NY
Status: Offline
Reply With Quote
May 3, 2003, 04:53 PM
 
this is the final script, in case you're interested. (i added some audible feedback as well!)

-- Say hello
tell current application
say "restarting summary"
end tell

-- Quit Summary
tell application "Summary 2.3.3"
quit
end tell

-- Wait for Summary to quit
delay 5

-- Launch Summary
tell application "Summary 2.3.3"
activate
end tell

-- Hide Summary
tell application "System Events"
set visible of process "Summary 2.3.3" to false
end tell

-- Say goodbye
tell current application
say "downloading new stats now"
end tell
     
Gary Kerbaugh
Dedicated MacNNer
Join Date: Jul 2001
Location: NC
Status: Offline
Reply With Quote
May 3, 2003, 11:14 PM
 
Originally posted by Rainy Day:
But this problem which you mention is exactly why i suggested a repeat while (the process theApp exists) loop.
Hi Rainy Day,
   Thanks for the info about delay; that's a good thing to know. I have a question. "process" is in the dictionary of System Events. I've used it in 'tell application "System Events"' blocks but I didn't think it possible to use it outside such a block. Is that wrong?
   Thanks again for all the info; this was an enlightening thread.
Gary
A computer scientist is someone who, when told to "Go to Hell", sees the
"go to", rather than the destination, as harmful.
     
Rainy Day
Grizzled Veteran
Join Date: Nov 2001
Location: Oregon
Status: Offline
Reply With Quote
May 4, 2003, 03:25 AM
 
"process" is in the dictionary of System Events. I've used it in 'tell application "System Events"' blocks but I didn't think it possible to use it outside such a block. Is that wrong?
You're not wrong, per se, but not entirely right either! It can be used inside a tell application "Finder" block as well, as in:
Code:
tell application "Finder" get the name of every process end tell
As far as i know, there's no advantage to one over the other. Use whichever is most convenient at the time.
     
mokolabs  (op)
Fresh-Faced Recruit
Join Date: Jul 2001
Location: New York NY
Status: Offline
Reply With Quote
May 4, 2003, 11:08 AM
 
As far as i know, there's no advantage to one over the other. Use whichever is most convenient at the time.
If you keep the Event Log open, it looks like the Finder passes off this command to System Events -- so it's an extra step, but one that doesn't seem to eat up much time.

(In the world of OSX, hiding apps shouldn't really be a Finder call anyway.)

Here's my script:
.........................
tell application "Finder"
set visible of process "Summary 2.3.3" to false
end tell

Here's the output:
...........................
tell application "Finder"
set visible of process "Summary 2.3.3" to false
end tell
tell application "System Events"
set visible of process "Summary 2.3.3" to false
end tell
( Last edited by mokolabs; May 4, 2003 at 11:20 AM. )
     
Rainy Day
Grizzled Veteran
Join Date: Nov 2001
Location: Oregon
Status: Offline
Reply With Quote
May 4, 2003, 02:38 PM
 
It looks like the Finder passes off this command to System Events -- so it's an extra step
That's a very good point, actually. The Finder supports process as part of its legacy suite, and supports it by passing it off to "System Events." I had forgotten that. If you wish for your script to be backwards compatible with OS 9, you should call process via the Finder. But if you're writing for MacOS X only, it would be best to choose "System Events," all else being equal, as it is more efficient and, someday, the Finder may drop support for it. Also, it may not be a good assumption that the Finder is actually active. If someone is running Path Finder (aka Snax), for example, a process reference inside a Finder tell block would cause the Finder to launch. Obviously, if you're writing a quick script for yourself, this is still somewhat arbitrary, but good form would dictate opting for "System Events" over "Finder," in my opinion.

Also, the current version of the Finder does not support the classic property of process.

On a side note, i assume that everyone knows about the Script Editor 2.0 beta. It's a vast improvement over the old Script Editor. Requires MacOS X 10.2 or better to run.
     
   
 
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Top
Privacy Policy
All times are GMT -4. The time now is 12:30 PM.
All contents of these forums © 1995-2017 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.8 © 2000-2017, Jelsoft Enterprises Ltd.,