ecuguru has asked for the wisdom of the Perl Monks concerning the following question:

I'm running Mac OSX 10.4, perl 5.8.1.
I'd like to be able to issue a command to the system, and get all of the results of my console command.
Specifically, I'm trying to find out if my perl service is running, and if not, I'll restart it.

Now, I don't want to talk about how long it took for me to determine this, but the way I'm doing it below is dependent on the size of the terminal window that the code is executing within. So if I have my window open wide enough, then my perl script gets the entire result like:
user 28066 0.0 1.0 34356 10032 p3 S+ 2:49PM 2:21.94 perl /Library/code/Theservice.pl
But if my terminal window isn't open wide enough to get the entire screen, then the code doesn't see the end part with the "Theservice", and thinks the service is dead.

There has to be a better way of trying to find out if services are running, than worrying about if the terminal window that I have my code open within is wide enough to capture the results.
Help, please?
thanks!
open(PS_F, "ps - aux | grep perl |") || die "Can't open console\n"; while (<PS_F>) { ($pid,$tt,$stat,$time,$comm,$comm1,$comm2) = split; $comm .= ' '.$comm1.' '.$comm2; if($comm =~ m/Theservice.pl /i) { print "Service Already Running\n"; } } close(PS_F);

Replies are listed 'Best First'.
Re: Capture Console Results?
by Corion (Patriarch) on Feb 24, 2006 at 20:22 UTC

    If you're looking for a solution in Perl, File::Pid might be what you want - it gives you a file with the pid of your server process which you can then use to check.

    Personally, I use a shell script to check/start services:

    #!/usr/bin/ksh # Should work with any other shell too if [ ! ps -aux | grep "/home/corion/myservice.pl" ]; then echo "(Re)starting myservice"; exec /home/corion/myservice.pl >/dev/null fi
Re: Capture Console Results?
by chargrill (Parson) on Feb 24, 2006 at 21:25 UTC

    My mac lets me specify ps -auwwx which will show you the ENTIRE command line for every process. Note, just one 'w' just gives you a 'standard wide' width result list, the extra 'w' goes the extra mile. But if you man ps on your mac, you'll see:

    ... -w Use 132 columns to display information, instead of the de +fault which is your window size. If the -w option is specified + more than once, ps will use as many columns as necessary witho +ut regard for your window size. ...

    ... this will also work on Linux (if you drop the preceeding '-' to the auwwx) and FreeBSD. Though I think I like the "pure perl" solution a bit better.

    Update: I made some changes to your open and your split to make sure I wasn't leading you astray. Note that the command is "ps -auwwx" as opposed to "ps - aux" (please notice the space I have omitted) plus I'm throwing away all the rest of the bits of the results I don't care about. Also note that there are more columns returned with the modification of ps

    open(PS_F, "ps -auwwx | grep inder |") || die "Can't open console\n"; while (<PS_F>) { (undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,$comm +,$comm1,$comm2) = split; $comm .= ' '.$comm1.' '.$comm2; if($comm =~ m/Theservice.pl /i) { print "Service Already Running\n"; } print $comm, "\n"; } close(PS_F);

    Since I don't have Theservice.pl running, I'm grepping for "inder"... the output is:

    $ perl ps.pl /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder -psn_0_9 +17505 sh -c ps grep inder

    HTH



    --chargrill
    $/ = q#(\w)# ; sub sig { print scalar reverse join ' ', @_ } + sig map { s$\$/\$/$\$2\$1$g && $_ } split( ' ', ",erckha rlPe erthnoa stJu +" );
      Just a side note really, but I think that

      (undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,$comm,$comm1,$comm2) = split;

      is probably best written as

      ($comm, $comm1, $comm2) = (split)[10..12];


      acid06
      perl -e "print pack('h*', 16369646), scalar reverse $="

        True, but I made the assumption he cared about some of the columns as he went through the trouble of creating variables to store them (though the example script makes no use of them). aundef,<esc>l8. in vi (to repeat adding more 'undef,') was easier than typing out new variable names, plus gives a hint that there are more columns of output than the original command provides, and could therefore be turned back into variables should the OP so desire.



        --chargrill
        $/ = q#(\w)# ; sub sig { print scalar reverse join ' ', @_ } + sig map { s$\$/\$/$\$2\$1$g && $_ } split( ' ', ",erckha rlPe erthnoa stJu +" );
        Actually I do care about the variables that come before it, but I didn't know that you could even do what you're suggesting, so thanks!!
      Thanks for the -ww tip. Now I see the entire line wrapped, but depending on the window size, the same problem still exists with -ww. Although it does show the entire line (wrappped), if the window has a size that happens to cause the word you're searching for to split between the lines, then the code doesn't find it because your search word has a \n in it not matching the grep. Rather than doing a foreach, I'll get rid of the \ns, and do a search for the string from the entire result, rather than going line by line. That should work (will update either way).
        That didn't work. The console, if the window is a certain size, will wrap the lines but it actually appears to cutoff part of the line (even with the ww added). Can I force resize a window, tell the system to pretend my console is a certain size and not wrap the lines, or is there any other way to disregard the size of the window in the script and get the whole output dumped to memory somewhere?
        28066 p3 S+ 353:01.11 perl /Library/WebServer/Documents/perlscr +ipts/refresh/getDat ##This is supposed to be getDataLive.pl script + i want to monitor. 571 std S+ 0:00.05 perl systemcmd.pl ##The name of my script +file 590 std S+ 0:00.02 sh -c ps - auwwx | grep perl 592 std R+ 0:00.00 grep perl
        Wondering if I'm making this harder than it has to be. Would like to keep from using launchd, not all the mac platform use launchd for services.
        Current code below
        open(PS_F, "ps - auwwx | grep perl |") || die "Can't open cons +ole\n"; my @data = <PS_F>; close(PS_F); my $res_data = join(" ",@data); print "Res data is $res_data\n---\n"; my $comm = $res_data; $comm =~ s/\n//g; $comm =~ s/\r//g; if($comm =~ m/getDataLive.pl/i) {
Re: Capture Console Results?
by Fletch (Bishop) on Feb 24, 2006 at 21:58 UTC

    Why not just use the facility the OS provides (i.e. launchd) to keep the process running?