The macosxhints Forums

The macosxhints Forums (http://hintsforums.macworld.com/index.php)
-   UNIX - Newcomers (http://hintsforums.macworld.com/forumdisplay.php?f=15)
-   -   Applescript and Unix commands (check if process exists) (http://hintsforums.macworld.com/showthread.php?t=34109)

atFault 01-28-2005 05:46 PM

Applescript and Unix commands (check if process exists)
 
Ok, I'm totally green at this and I've been at it for hours. This is all I have to show for it:

Code:

on idle
        tell application "System Events" to get name of every process
        if the result does not contain "server-bin" then
                tell application "Terminal"
                        activate
                        do script with command "cd //Applications/Army\\ Operations\\ 2.1.0.app/System; ./server-bin global sfcsar.aao"
                end tell
        end if
        return 60
end idle

It seems that "tell application "System Events" to get name of every process" does not return 'server-bin' even though it shows up in Activity Monitor or using top. Other than that, the script works and runs 'do script with command... ' every minute because System Events does not return true to server-bin.

Is there another way to make this work? Either through AppleScript or adding to it and using terminal commands?

Any help would be greatly appreciated.

hayne 01-28-2005 06:25 PM

You might do better with "if exists process" as in post #10 of this other thread:
http://forums.macosxhints.com/showthread.php?t=27113

You seem to be trying to restart a process that might have crashed. If so, see this other thread with an example of how to do this in a shell script (running in Terminal):
http://forums.macosxhints.com/showthread.php?t=24044

atFault 01-28-2005 07:31 PM

Quote:

Originally Posted by hayne
You might do better with "if exists process" as in post #10 of this other thread:
http://forums.macosxhints.com/showthread.php?t=27113

Unfortunately the 'if exist process' still uses System Events which does not see 'server-bin' running

I looked at the suggested examples and came up with this:
Code:

on idle
        tell application "Terminal"
                activate
                do script with command "ps ax | grep safari | grep -v grep; if [ $? = 0 ]; then; else; cd //Applications/Army\\ Operations\\ 2.1.0.app/System; ./server-bin global sfcsar.aao; fi"
        end tell
        return 60
end idle

Which returns this : tcsh: if: Expression Syntax. And of course everyminute it opens a new terminal window. Can I run a script like this on one line? Can I make it use the same window again?

I would really like to use Applescript because I can save the script as a Stay open application. Is there no way applescript can check all running system processes?

Sorry if this looks totally newb, but I have no idea how to implement scripts with Terminal.

hayne 01-28-2005 07:39 PM

1) You might want to read some Unix tutorials, e.g. the one here:
http://www.osxfaq.com/Tutorials/LearningCenter/

2) Don't bother with trying to run a complicated command line from AppleScript. Instead, make those commands into a shell script and then run the script from AppleScript. See #1 above on making shell scripts.

3) To pursue your original tack of using System Events to list the processes, you should figure out why it isn't finding the process you named. To do this, I would start by just doing some AppleScript to show you all the names of the processes. Probably you will see that the process you are looking for has some different name than what you think.

mark hunte 01-28-2005 09:43 PM

Hayne, usually The processes I look for are applications, I notice that atFault is not, and thought that maybe it was a case sensitive spelling problem.
So tested the script. on a process called pmTool, but typing it pmtool.

The script did not find it as I expected. But when I corrected the t to T it still did not find it.

The script work as expected when looking for an app name like Safari.

So I then used a applescript with a do shell script "ps -ax | grep -e pmtool" to check for pmtool and then I tried pmTool. that script found both. with and without the -i option.

hayne 01-28-2005 10:22 PM

Yes - I think you are right. I did a few experiments running the simple AppleScript:
Code:

tell application "System Events" to get name of every process
by using 'osascript' in a command in a Terminal window. This prints out the results as a comma-spearated list.
Only the programs that gave some GUI component show up in the results.
I think it might only be reporting on the apps that make a connection to the WindowServer process.

atFault:
It looks like you will need to use a solution based on 'ps' in a shell script.

atFault 01-29-2005 01:36 PM

Ok, I've been trying other stuff and am here:

Code:

on idle
        set cmdOutput to do shell script "ps ax | grep server-bin | grep -v grep"
        if cmdOutput contains "server-bin" then
                nothing
        else
                tell application "Terminal"
                        activate
                        do script with command "cd //Applications/Army\\ Operations\\ 2.1.0.app/System; ./server-bin global sfcsar.aao"
                end tell
        end if
        return 60
end idle

I know this part works properly because if I have just that in a script it works.
Code:

tell application "Terminal"
                        activate
                        do script with command "cd //Applications/Army\\ Operations\\ 2.1.0.app/System; ./server-bin global sfcsar.aao"
end tell

So it must be something with
Code:

set cmdOutput to do shell script "ps ax | grep server-bin | grep -v grep"
        if cmdOutput contains "server-bin" then
                nothing
    else

I still get a Type 1 on error from the script. I have no idea how exact the "if cmdOutput contains "server-bin"" results must be to the actual output from the "ps ax | grep server-bin | grep -v grep" shell script. I hope it can be generalized because the process ID is different everytime it runs "server-bin". Is there a way to filter the result any more? Is "ps ax | grep server-bin | grep -v grep" the right thing to be using? Applescript is new, but Unix is completely foreign.

Again, any help would be greatly appreciated.

mark hunte 01-29-2005 02:12 PM

Take out the second grep pipe ( | grep -v grep" ), with the second pipe you are saying invert the result ( select non-matching lines ) so there is no match.

hayne 01-29-2005 03:12 PM

Quote:

Originally Posted by mark hunte
Take out the second grep pipe ( | grep -v grep" ), with the second pipe you are saying invert the result ( select non-matching lines ) so there is no match.

The second grep is necessary to filter out the process corresponding to the first grep.

atFault:
The way to figure out what is happening (what is going wrong) is to proceed step by step. Don't try to get your 'if' statement working. Just run an AppleScript (in Script Editor) that has the line
do shell script "ps ax | grep server-bin | grep -v grep"
and look at what the result is (shown in one of Script Editor's windows).
Then you will see what that script is returning and hence why the 'if' statement isn't working.

But really you are making things much harder on yourself by continuing to debug this from AppleScript. When you are dealing with a shell script, it really is essential to get it working first in Terminal, and only then, once you have it working and understand its output, wrap it up inside AppleScript. You are being hampered by the AppleScript wrapper.
I.e. I think you need to go and read that Unix tutorial I suggested. Then try out the commands in Terminal, etc. Step by step.

atFault 01-29-2005 03:24 PM

Quote:

Originally Posted by hayne
The second grep is necessary to filter out the process corresponding to the first grep.

atFault:
The way to figure out what is happening (what is going wrong) is to proceed step by step. Don't try to get your 'if' statement working. Just run an AppleScript (in Script Editor) that has the line
do shell script "ps ax | grep server-bin | grep -v grep"
and look at what the result is (shown in one of Script Editor's windows).
Then you will see what that script is returning and hence why the 'if' statement isn't working.

But really you are making things much harder on yourself by continuing to debug this from AppleScript. When you are dealing with a shell script, it really is essential to get it working first in Terminal, and only then, once you have it working and understand its output, wrap it up inside AppleScript. You are being hampered by the AppleScript wrapper.
I.e. I think you need to go and read that Unix tutorial I suggested. Then try out the commands in Terminal, etc. Step by step.


I have been doing things line by line and trying the shell commands in the terminal. It all seems right, but the problem seems to be that while
Code:

do shell script "ps ax | grep server-bin | grep -v grep"
returns
Code:

"15655  p1  R+    33:40.43 ./server-bin global sfcsar.aao"
it seems that
Code:

if cmdOutput contains "server-bin" then
is not the right line to make sense of the result to continue running if/then/else situation.

mark hunte 01-29-2005 03:34 PM

Hayne can you explain how grep -v does this filter?

I obviously did not understand the man page and miss reading the script.

so the ps ax | - looks at the process an pipes it to

grep "server-bin" | - which looks for server-bin and pipes that to

grep -v grep"

which does what? if you mean it looks for grep in the result of
grep "server-bin"

then does not the -v tell the last grep to ignore all lines with grep

??

hayne 01-29-2005 03:46 PM

Quote:

Originally Posted by atFault
it seems that
Code:

if cmdOutput contains "server-bin" then
is not the right line to make sense of the result to continue running if/then/else situation.

This sort of thing works for me.
Maybe the problem is with the action you are taking inside the 'if' statement. Instead of doing some action like in your first example script,
just set a variable.
E.g. something like:
Code:

set cmdOutput to do shell script "ps ax | grep server-bin | grep -v grep"
if cmdOutput contains "server-bin" then
    set foo to "found it"
else
    set foo to "nope"
end if
foo

That will print out the value of the variable 'foo'
As I said, when I do this sort of thing, it works.

hayne 01-29-2005 03:49 PM

Quote:

Originally Posted by mark hunte
does not the -v tell the last grep to ignore all lines with grep

Exactly.
Just run the command without the second grep (and do the search for a process that you know is running - e.g. run a 'sleep 100' in another Terminal window):

ps ax | grep sleep

Then you will understand.

atFault 01-29-2005 04:49 PM

Quote:

Originally Posted by hayne
This sort of thing works for me.
Maybe the problem is with the action you are taking inside the 'if' statement. Instead of doing some action like in your first example script,
just set a variable.
E.g. something like:
Code:

set cmdOutput to do shell script "ps ax | grep server-bin | grep -v grep"
if cmdOutput contains "server-bin" then
    set foo to "found it"
else
    set foo to "nope"
end if
foo

That will print out the value of the variable 'foo'
As I said, when I do this sort of thing, it works.


This kind of works. If server-bin is running foo returns "found it". If it isn't I get "An error of type 1 occured". It really seems to be the "if cmdOutput contains "server-bin" then" line. Everything else works, but why would that line give an error if the the result of "set cmdOutput to do shell script "ps ax | grep server-bin | grep -v grep"" is null?

If i put "ps ax | grep server-bin | grep -v grep" into terminal while 'server-bin' is not running I get nothing returned. Of course that makes sense because there is nothing to return and "grep -v grep" is ignoring the "grep server-bin".

The same thing happens with

Code:

set cmdOutput to do shell script "ps ax | grep Safari | grep -v grep"
if cmdOutput contains "Safari" then
        set foo to "found it"
else
        set foo to "nope"
end if
foo

"An error of type 1 occured" if Safari is not running. Is there a way to cause an output of somekind depending on the result in order to avoid a null output?

I really appreciate the the help you guys are giving me. Hopefully I will be able to sleep tonight and not thing about conditions :rolleyes:

hayne 01-29-2005 07:35 PM

Okay, I see the same problem - if the shell script doesn't print any text, then you get an error in AppleScript.

You could add error handling in your AppleScript ('try' & 'on error' - search these forums for examples) but it seems to me that would be a kludge.
The correct thing to do would be to write a shell script (based on your 'ps' & 'grep' command) that printed either "running" or "not running". Then you could use that shell script in the AppleScript.

I supplied such a shell script in the thread I referred to above:
http://forums.macosxhints.com/showthread.php?t=24044

mark hunte 01-29-2005 08:36 PM

Quote:

Exactly.
Just run the command without the second grep (and do the search for a process that you know is running - e.g. run a 'sleep 100' in another Terminal window):

ps ax | grep sleep

Then you will understand.
Ah, I see, you get

535 std R+ 0:00.00 grep sleep
533 p2 S+ 0:00.02 sleep 100

on my first tests with pmtool, I was only getting the one line which had grep in. So again its dependent on the type of process.

hayne 01-29-2005 08:42 PM

Quote:

Originally Posted by mark hunte
on my first tests with pmtool, I was only getting the one line which had grep in. So again its dependent on the type of process.

Sorry if I'm beating a dead horse, but no, it doesn't depend on the type of process. If you only get the one line with the grep, that means that the process you were grep'ing for does not exist. (In your first try, you told us that you had misspelled the name of the process)

mark hunte 01-29-2005 09:24 PM

Its not your horse that needs flogging, I think it must be me,

But what I mean by my first test, was actually the one I did with

ps ax | grep server-bin | grep -v grep"

I do not have the server-bin so I used pmTool again in terminal.

ps ax | grep pmtool | grep -v grep

and | open -f

to see the result.

which returned nothing.

but

ps ax | grep pmTool | open -f

returned only the one line.

560 std R+ 0:00.00 grep pmtool

and I got the same regardless if its 't' or 'T'


This is why I did not get the use of the filter because I was only getting one line.

So I now know why you needed to use the filter for grep,
but whats throwing me is the inconsistent results compared to what you are getting.

( the pmTool is running but I am only getting one line )

hayne 01-29-2005 10:03 PM

Quote:

Originally Posted by mark hunte
but whats throwing me is the inconsistent results compared to what you are getting.
( the pmTool is running but I am only getting one line )

1) I don't know why you are using 'open -f' to see the results. The results will appear in the Terminal window if you just do:
ps ax | grep pmTool

2) If the process doesn't show up, you need to check that it is appearing in the output from 'ps ax'. I.e. just run the command:
ps ax
and look at the output to see if you see the line with pmTool
Maybe the problem is that the output from 'ps ax' is truncated at 80 characters. Try 'ps axww' to get the untruncated output.

mark hunte 01-29-2005 10:45 PM

Quote:

Maybe the problem is that the output from 'ps ax' is truncated at 80 characters. Try 'ps axww' to get the untruncated output.
Yer that was the problem.
I now get

402 ?? Ss 17:33.68 /Applications/Utilities/Activity Monitor.app/Contents/Resources/pmTool
672 std R+ 0:00.00 grep pmTool

so now when I do
ps axww | grep pmTool | grep -v grep

I get

402 ?? Ss 17:41.83 /Applications/Utilities/Activity Monitor.app/Contents/Resources/pmTool

Which means I am getting what I should be.

I understand now the grep -v grep .
And I will remember about that truncation. ( I hope )
EDIT**
And should have read your link
Thanks and Thanks for your patience.

atFault 01-31-2005 07:10 PM

Now to recapture my hijacked thread and post my solution.

I took the "grep -v grep" off of the set "cmdOutput to do shell script "ps ax | grep server-bin"" line so that I would get both the grep of the grep and the grep of the server-bin thereby eliminating the NULL condition.

Code:

24931  p1  R+    27:40.28 ./server-bin global sfcsar.aao
25159 std  R+    0:00.00 grep server-bin

I then modified 'if cmdOutput does not contain "sfcsar" then" to query for a different, but unique return from the "ps ax | grep server-bin" that would not be present if "server-bin" wasn't running. It turns out the NULL condition was the cause of my 'A type 1 error occured" message and this solved the problem.

My final script is this:
Code:

on idle
        set cmdOutput to do shell script "ps ax | grep server-bin"
        if cmdOutput does not contain "sfcsar" then
                tell application "Terminal"
                        activate
                        do script with command "cd //Applications/Army\\ Operations\\ 2.1.0.app/System; ./server-bin global sfcsar.aao"
                end tell
        end if
        return 60
end idle

So I figured it out on my own, but there is no way I would have put it all together without you guys, thanks for the pointers and info. It even sounds like the hijackers got something from my little problem. I don't know how 'clean' my script is or how appropriate it is to make it work like this, but it does work and is making many people happy.

Ciao, and thanks again

atFault

jkenney 02-01-2005 12:33 AM

Just a helpfull pointer...

ps -axc to take out the path name of the application

for example:

Code:

[:~] jkenney% ps -ax | grep init
    1  ??  Ss    0:00.01 /sbin/init -v
    2  ??  Ss    0:02.16 /sbin/mach_init -v
20570 std  R+    0:00.00 grep init
[:~] jkenney% ps -axc | grep init
    1  ??  Ss    0:00.01 init
    2  ??  Ss    0:02.16 mach_init
[:~] jkenney%

See the difference... type man ps to find more ps fun :)

bcjenkins 05-26-2008 09:59 AM

Thought I would dust this thread off and post my solution in case it is helpful to anyone else.

Code:

set isRunningComskip to do shell script "ps ax | grep comskip.exe | grep -v grep | wc -l | cut -d ' ' -f8"
The wc command will return 0 if it is not running. And in my case, I want to allow more than one instance running of comskip.exe under wine, so this serves two purposes. It tells me if it is running, and how many instances.

B

Hal Itosis 05-27-2008 03:00 AM

As jkenney pointed out (though perhaps not emphatically enough),
using the 'c' option with ps not only trims off the pathname... but,
ALSO totally obviates the need for the extra |grep -v grep !

If someone can explain *why* that actually works, I'm all ears.
[seems like grep should still find the same string it did before?]

--

Another trick -- which works without the 'c' option -- is to prefix a [/]
bracket expression onto the searched name. So grep must then match
a leading / forward slash, right before the string. Thus -- for example,
to see if Safari is running -- this will do the trick:
Code:

if [[ $(ps ax |grep [/]Safari) ]]
then
        # Safari is running...

else
        # Safari NOT running...

fi

§

Quote:

Originally Posted by bcjenkins (Post 472182)
Thought I would dust this thread off and post my solution in case it is helpful to anyone else.
Code:

set isRunningComskip to do shell script "ps ax |
grep comskip.exe | grep -v grep | wc -l | cut -d ' ' -f8"

The wc command will return 0 if it is not running. And in my case, I want to allow more than one instance running of comskip.exe under wine, so this serves two purposes. It tells me if it is running, and how many instances.

I will also briefly mention that that final pipe into "|cut -d ' ' -f8" is pretty much not needed.
Yes... wc does stick a bunch of spaces in there, for some odd reason.
But the shell sees spaces as nothing but separation: IFS=$' /t/n'
So... it can still do math, and "if" comparisons, etc., just fine.
For most purposes, simply don't quote the (integer) variable... and the spaces go away!
E.g.:
if [ $isRunningComskip -gt 0 ]
or
(( $isRunningComskip+=1 ))
or
echo $isRunningComskip
all work fine. (the spaces are simply ignored/discarded)

-HI-

hayne 05-27-2008 10:18 AM

Quote:

Originally Posted by Hal Itosis (Post 472379)
using the 'c' option with ps not only trims off the pathname... but,
ALSO totally obviates the need for the extra |grep -v grep !

If someone can explain *why* that actually works, I'm all ears.
[seems like grep should still find the same string it did before?]

Here's an example that should lead you to the path of understanding:
Code:

% ps -ax | grep grep
19539 ttys000    0:00.00 grep grep

% ps -axc | grep grep
19541 ttys000    0:00.00 grep


bcjenkins 05-27-2008 03:18 PM

Quote:

Originally Posted by Hal Itosis (Post 472379)
As jkenney pointed out (though perhaps not emphatically enough),
using the 'c' option with ps not only trims off the pathname... but,
ALSO totally obviates the need for the extra |grep -v grep !

If someone can explain *why* that actually works, I'm all ears.
[seems like grep should still find the same string it did before?]

--

Another trick -- which works without the 'c' option -- is to prefix a [/]
bracket expression onto the searched name. So grep must then match
a leading / forward slash, right before the string. Thus -- for example,
to see if Safari is running -- this will do the trick:
Code:

if [[ $(ps ax |grep [/]Safari) ]]
then
        # Safari is running...

else
        # Safari NOT running...

fi

§



I will also briefly mention that that final pipe into "|cut -d ' ' -f8" is pretty much not needed.
Yes... wc does stick a bunch of spaces in there, for some odd reason.
But the shell sees spaces as nothing but separation: IFS=$' /t/n'
So... it can still do math, and "if" comparisons, etc., just fine.
For most purposes, simply don't quote the (integer) variable... and the spaces go away!
E.g.:
if [ $isRunningComskip -gt 0 ]
or
(( $isRunningComskip+=1 ))
or
echo $isRunningComskip
all work fine. (the spaces are simply ignored/discarded)

-HI-

Ahh, thanks for that tip on cut. I may give that a whirl, although I wrapped my package already. For the record I had to use
Code:

set isRunningComskip to do shell script "ps ax |
grep comskip.exe | grep -v grep | wc -l | cut -d ' ' -f8"

When using c, it captured I was running bash, but not the name of the bash script.

B

Hal Itosis 05-27-2008 11:14 PM

Quote:

Originally Posted by hayne (Post 472456)
Here's an example that should lead you to the path of understanding:
Code:

% ps -ax | grep grep
19539 ttys000    0:00.00 grep grep

% ps -axc | grep grep
19541 ttys000    0:00.00 grep


Not really. In fact... that makes it more mysterious. :D
[i can see it does work... but not how/why it works.]

Try this:
$ ps -ax | grep Safari
88880 ?? 0:39.45 /Applications/Safari.app/Contents/MacOS/Safari -psn_0_454767
94274 ttys000 0:00.00 grep Safari

$ ps -acx | grep Safari
88880 ?? 0:39.45 Safari

Now... why doesn't the 2nd grep *also* see itself (grepping Safari)?
The text being matched is simply "Safari"... so, i don't get it.

Hal Itosis 05-27-2008 11:24 PM

Quote:

Originally Posted by bcjenkins (Post 472515)
Ahh, thanks for that tip on cut. I may give that a whirl, although I wrapped my package already. For the record I had to use
Code:

set isRunningComskip to do shell script "ps ax |
grep comskip.exe | grep -v grep | wc -l | cut -d ' ' -f8"

When using c, it captured I was running bash, but not the name of the bash script.

Perhaps I should have emphasized that those behaviors apply to Bash, and not AppleScript.

However, most of the examples in this thread seem to use AppleScript only to
either talk to the shell (do shell script) or Terminal (tell application "Terminal").
So --unless there's some use for it [not shown] -- a shell script should suffice.

But yes, to have AppleScript display that number as text, we'd need to strip
the spaces (if we cared about it looking perfect). I much prefer sed over cut:
Code:


--begin applescript
set theApp to "Safari"
set isRunning to do shell script "ps ax |
        grep [/]" & theApp & " |wc -l |sed 's/ //g'"

if isRunning > 0 then -- !!! need to have removed wc's spaces, or that ">" won't work
        display dialog "the count is " & isRunning
end if


hayne 05-28-2008 12:42 AM

Quote:

Originally Posted by Hal Itosis (Post 472648)
Now... why doesn't the 2nd grep *also* see itself (grepping Safari)?
The text being matched is simply "Safari"... so, i don't get it.

Look again at the 'grep grep' example I showed above.
The output from the 'ps -axc' case shows that the line in the output from the 'ps' command with those options is simply "19541 ttys000 0:00.00 grep"
- there is no "grep grep" in the 'ps' output.

Similarly when you 'grep Safari', there is no "Safari" in the line from 'ps' for that process since the "-c" option does not include the command's arguments in the output.

Or here's another way to understand:
Run a shell script that loops, running a command like 'grep foo /etc/passwd'
and then look at the full output from 'ps -xc' with something like:
ps -axc | more

Hal Itosis 05-28-2008 12:55 AM

Quote:

Originally Posted by hayne (Post 472662)
Similarly when you 'grep Safari', there is no "Safari" in the line from 'ps' for that process since the "-c" option does not include the command's arguments in the output.

No arguments!
*NOW* I get it.

[duh :o ]

Thanks C.H.

bcjenkins 06-04-2008 09:14 AM

Quote:

Originally Posted by Hal Itosis (Post 472649)
Perhaps I should have emphasized that those behaviors apply to Bash, and not AppleScript.

However, most of the examples in this thread seem to use AppleScript only to
either talk to the shell (do shell script) or Terminal (tell application "Terminal").
So --unless there's some use for it [not shown] -- a shell script should suffice.

But yes, to have AppleScript display that number as text, we'd need to strip
the spaces (if we cared about it looking perfect). I much prefer sed over cut:
Code:


--begin applescript
set theApp to "Safari"
set isRunning to do shell script "ps ax |
        grep [/]" & theApp & " |wc -l |sed 's/ //g'"

if isRunning > 0 then -- !!! need to have removed wc's spaces, or that ">" won't work
        display dialog "the count is " & isRunning
end if


I had a friend explain sed to me the other day. It is much cleaner and doesn't suffer from the limitation I found in cut. If the # of processes is 10 or higher, the field changes to 7 from 8.

B


All times are GMT -5. The time now is 10:21 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.