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

Hello all: I'm collecting our department's little monitoring scripts that do various "watching" of Solaris, OSX, and Linux server directories to make sure that files fed into said directories are moving through (ie: dropping in and being moved out) via other automated processes. We have a nifty clustered "watch" server that monitors this sort of thing... my problem is that I can verify that the remote directory to be watched exists, can even return an array populated by the remote directory listing but I'm doing really bad things to try and get a "stat()" of each of the files to compare file mtime to my system time...
... $FileTime = `ssh $ServerName 'perl -e '(stat($FP_RemoteFile))[9];''`;
$FileTime, then should contain the mtime value from the stat array... that is if it actually worked without returning syntax errors like "sh: syntax error at line 1: `(' unexpected"... Anyone know how best to gather the mtime from a remote file using an ssh call in a perl script? Thanks! baerlun

Replies are listed 'Best First'.
Re: Comparing localtime to a remote file's modification time.
by ikegami (Patriarch) on Oct 23, 2006 at 20:02 UTC
    $FileTime = `ssh $ServerName 'perl -e '(stat($FP_RemoteFile))[9];''`; ^ ^ | | this is quote closed here

    You need to escape the 2nd and 3rd single quote. I don't know how to do that in your shell. Perhaps you need to preceed them by \\ (one slash for the shell, and a second one to escape the shell's slash for Perl).

      I'm using bourne for this... but escaping the single quotes like this: $FileTime = `ssh $ServerName \'perl -e \'(stat($FP_RemoteFile))[9];''`; or $FileTime = `ssh $ServerName \'perl -e \'(stat($FP_RemoteFile))[9];\'\'`; gives me the same syntax errors. (sh: syntax error at line 1: `(' unexpected) It looks as though the shell is actually complaining and, therefore, I guess I should assume that the perl one-liner format (quoting) is incorrect? In this, Ikegami, you may be on the right track. I'd love to put this in a script on the remote machine and run it from our watch server but then I'd need tiny scripts on every server that needs to be watched. This would make things a bit too complex to maintain. Is there no way to stat a remote file using ssh from within a perl script and capture the output?

        When Perl sees \' in a string literal, it places just ' in the string, so you haven't changed anything.

        You seem to have missed half of my comment.
        I didn't suggest that you escape the 1st and 2nd ' with \.
        I didn't suggest that you escape all the ' with \.
        I suggested that you escape the 2nd and 3rd ' with \\.

        $FileTime = `ssh $ServerName 'perl -e \\'(stat($FP_RemoteFile))[9];\\''`;
        executes
        ssh $ServerName 'perl -e \'(stat(...))[9];\''
        which executes
        perl -e '(stat(...))[9];'
        on the remote machine if sh behaves as I think it does.

        Update: stat($FP_RemoteFile) is also wrong. You need to convert the contents of $FP_RemoteFile into a Perl literal, then you must escape it for sh.

Re: Comparing localtime to a remote file's modification time.
by Fletch (Bishop) on Oct 23, 2006 at 20:17 UTC

    Unless you enjoy puzzling out the different levels of quoting it's easiest to put the complex command you want run on the remote side in a shell script and then use ssh to invoke that instead of trying to figure out which of the layers of shell your command is passing through is going to eat what quotes.

Re: Comparing localtime to a remote file's modification time.
by Cabrion (Friar) on Oct 24, 2006 at 01:37 UTC
    Not that you aksed, but I thought I might mention that mtime as reported by perl's stat() is based on an offset from the local operating system's epoch. The epoch can vary from platform to plaform. That may or may not matter to you, but you should keep it in mind if you decide to start comparing mtimes from system to system.

    Updated
    Oops... I think perl defines it's own portable epoch, however 'perldoc -f stat' warns about portability of ctime on my plaform. You should check the perldocs for each system just to be safe.

Re: Comparing localtime to a remote file's modification time.
by andreas1234567 (Vicar) on Oct 24, 2006 at 11:05 UTC
    I'm collecting our department's little monitoring scripts that do various "watching" of Solaris, OSX, and Linux server directories.

    I suggest you take a look at Cfengine, which is a "tool for setting up and maintaining computer systems". It's incredibly powerful, and will allow you to control your systems, enforce rules, check status, etc.

    Licenced under GNU GPL.

    Andreas
    --
      I've just been browsing the Cfengine's functionality actually! Thanks for the advice... now to convince the entire department to scrap our home-grown solution ;)
        In this ONLAMP article, Æleen Frisch, author of Essential System Administration, ranked Cfengine #1 in her Top Five Open Source Packages for System Administrators. The article illustrates parts of what can be done with Cfengine.

        You may very well incorporate your custom shell or perl scripts with Cfengine, but as for basic task such as maintaining file permissions, monitor disk usage etc, go for the in-built functionality.

        I highly recommend Cfengine to any *nix system administrator.

        Andreas
        --