Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

How best to see if syslogd is running?

by Plankton (Vicar)
on Jan 03, 2005 at 20:48 UTC ( #419055=perlquestion: print w/replies, xml ) Need Help??

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

Friends

I want to translate a small bit of shell script to Perl.

Here's what I have in my shell script ...

... PID=`cat /var/log/syslogd.pid` RUNNING=`ps -ef | grep -v grep | grep $PID | wc -l` if [ $RUNNING != 1 ] then echo "syslog not running" fi ...
... Here's my lame attempt to translate this to Perl ...
sub is_syslogd_running { my $cmd = "ps -ef | grep -v grep | grep `cat /var/run/syslogd.pid`" +; my $rc = 1; open CMD, $cmd or return $rc; while( <CMD> ) { $rc = 0; } return $rc; }
... well that doesn't work to well and I suspect that the monks know a way-better way to do something like this. Can you help? :)

Replies are listed 'Best First'.
Re: How best to see if syslogd is running?
by Fletch (Chancellor) on Jan 03, 2005 at 20:51 UTC

    If you've already got the PID available just and you're running as the same UID you can use kill 0 => $pid to see if it's still running (see perldoc -f kill); otherwise you'll need to use ps or something like Proc::ProcessTable.

    Update:, Gah, had the wrong name for the module.

      Note: Sending a "kill 0" is preferable to ps, but make sure you run this as root (in the case of syslogd) since some systems will return a permission error if you aren't authorized to actually kill the target process.
Re: How best to see if syslogd is running?
by ambrus (Abbot) on Jan 03, 2005 at 21:08 UTC

    Don't mess with grepping, or even running ps. Get the pid, and kill 0, $pid; it to see if it's alive. If you must run ps, don't grep, but call it like ps h 1234 where 1234 is the pid wanted, and see if it outputs anything or even its exit status.

      Not that this isn't a good suggestion, but be careful as ps usage and arguments can vary greatly between OSen (and sometimes even between releases of the same OS :). While the example given works fine on Linux, on all three of OS X, FreeBSD, and OpenBSD it'll still print a header line even when given a single pid (the -h means "print headers every page of output" according to the man page, although it doesn't seem to do anything different that I can tell . . .).

      I won't even get into SysV-esque ps . . .

      Update: Reworded to make more clear that it's the BSD-y ones that insist on a header.

Re: How best to see if syslogd is running?
by sgifford (Prior) on Jan 04, 2005 at 03:08 UTC
    It looks to me like the problem with your code is it's missing a trailing pipe. If I use:
    my $cmd="ps -ef |grep -v grep |grep `cat /var/run/syslogd.pid` |"
    it works.

    A smarter solution would make sure that the PID running was actually syslog, in case syslogd died and another process started with the same PID:

    my $cmd = "ps -ef |grep -v grep |grep `cat /var/run/syslogd.pid` |grep syslogd |"

    One of the modules that acts as a frontend to ps is what you really want, though (see the other responses).

Re: How best to see if syslogd is running? (use Perl!)
by grinder (Bishop) on Jan 04, 2005 at 09:29 UTC

    Why all the futzing around with external programs when you can do it with just Perl?

    #! /usr/local/bin/perl -w use IO::Socket::INET; print "syslog is ", check_syslog( 'localhost' ) ? 'up' : 'down', "\n" +; sub check_syslog { my $s = IO::Socket::INET->new( PeerHost => $_[0], Timeout => 1, Proto => 'udp', PeerPort => 514, ); return 0 unless $s; close $s; return 1; }

    In other words, just see whether you can connect to the socket that syslogd opens. Much easier than fiddling around with ps, grep, pidfiles and/or procfs.

    - another intruder with the mooring of the heart of the Perl

Re: How best to see if syslogd is running?
by bageler (Hermit) on Jan 04, 2005 at 03:12 UTC
    how about:
    print "syslog not running" unless qx[ps -auxw | grep -v grep |grep `ca +t /var/run/syslogd.pid`];
Re: How best to see if syslogd is running?
by Anonymous Monk on Jan 04, 2005 at 10:25 UTC
    I would go further than checking the content of /var/run/syslogd.pid and seeing whether there's a process running with that id. After all, if syslogd went down, another process could have taken PID syslogd was using.

    Furthermore, to check whether a PID is in use, and what program is using it, I would use neither kill, nor ps. I'd run something like (untested):

    my $pidfile = "/var/run/syslogd.pid"; if (-e $pidfile && qx "cat /proc/`cat $pidfile`/cmdline" =~ /^syslogd$/) { ... syslog is running ... }
    Notes:
    • On my systems, you must be root to be able to read /var/run/syslogd.pid. Your milage may vary.
    • It's not foolproof. Something may have removed the PID file for instance.
    • This is for a 2.4 Linux kernel. Different OSses (or Linux versions) may have a different /proc file system layout, or no /proc filesystem at all. The information from the file cmdline may be elsewhere, or not available at all.
Re: How best to see if syslogd is running?
by BravoTwoZero (Scribe) on Jan 04, 2005 at 16:28 UTC

    Why not:

    $pid = "/var/log/syslog.pid"; unless (stat($pid)) { print "$pid not running\n"; }

    Is there a reason why running stat on the pid file is a Bad Idea? I'm not suggesting it's the best way, mind. I'm just wondering if it's acceptable.

    Updated: Thanks, bluto. I'd totally let that evacuate my brain. Cat the pid file to get the process id for which to grep in ps. Buh.

    So, just to run mine into the ground:

    $pid = "/var/run/syslogd.pid"; if (stat($pid)) { open(PID, "< $pid"); my $id = <PID>; chomp $id; if($id) { print "$id running\n"; } else { print "$pid not running\n"; } close PID; } else { print "$pid not running\n"; }

    ... but it's just for my own excercise at this point. The stat is pointless, since I could just as easily bail if it dies on opening the file in the file handle.



    --
    Amatuers discuss tactics. Professionals discuss logistics.

    And... my cat's breath smells like cat food.
      Because the existance of the file does not prove syslogd is currently running since it may have terminated and not cleaned up the pid file (e.g. it crashes for some strange reason or someone sends it a nontrapable signal like SIGKILL).

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://419055]
Approved by RolandGunslinger
Front-paged by RolandGunslinger
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2021-03-07 15:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favorite kind of desktop background is:











    Results (122 votes). Check out past polls.

    Notices?