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

I run an Apache Web server with many Virtual Hosts. The numbers of Virtual Hosts is increasing and I would like to streamline our administration of server logs. I would like to cron two jobs, weekly and monthly, to gzip and mail log files to the owners of the sites. Using find2perl /home/www/*/logs/weekly and find2perl /home/www/*/logs/monthly I can generate Perl code to search for files named weekly and monthly. Here's an example:
#! /usr/local/bin/perl -w eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}' f 0; #$running_under_some_shell use strict; use File::Find (); # Set the variable $File::Find::dont_use_nlink if you're using AFS, + # since AFS cheats. # for the convenience of &wanted calls, including -eval statements: + use vars qw/*name *dir *prune/; *name = *File::Find::name; *dir = *File::Find::dir; *prune = *File::Find::prune; # Traverse desired filesystems File::Find::find({wanted => \&wanted}, '/home/www/admin/logs/weekly', +'/home/www/nsms/logs/weekly'); exit; sub wanted { ; }
My plan is then to add some code to the wanted sub-routine which will gzip the logs held in /home/www/*/logs and mail it to site owners. Now to my problem. The number of virtual hosts changes from week to week. I would like to totally automate this process using Perl. I need to run the find2perl command to get a complete lsiting of all the relevant directories but when I run this it creates new code each time with a correct directory listing but with an empty "wanted" sub-routine. Is it possible to run my find2perl command and add the Perl code I want to use to gzip and mail the logs to the "wanted" sub-routine at the same time?

Replies are listed 'Best First'.
Re: Searching a directory tree
by davorg (Chancellor) on Aug 10, 2001 at 14:10 UTC

    I think you're slightly misusing find2perl. The idea behind find2perl is that you pass it a find command and it generates a Perl script which does the same thing as the orignal command. You can then run the Perl script instead of the find or find2perl.

    So, my solution would be to write a find command that does what you want and then pass that command thru find2perl to generate a Perl script which you can then run any time you want.

    --
    <http://www.dave.org.uk>

    Perl Training in the UK <http://www.iterative-software.com>

      Thanks for your reply Dave.

      Unless I'm missing something obvious I think that is what I am doing already.

      My find command isfind/home/www/*/logs/weekly i.e find all subdirectories, including new ones created since the job was last run, below /home/www that contain a logs sub-directory containing the file "weekly". This is what I want to do. The job will be run weekly using cron. Find2perl writes the code to find the files correctly but also creates a blanksub wanted{} sub-routine each time the cronned script is run.

      I then want to pass the gzip and mail commands to the "wanted" sub-routine.

      Any ideas?

      Thanks in advance.

        I think you're missing the power of the Unix find coomand :) find will not only find the file that you want, but it will also carry out the correct operations on them. find2perl will then fill in the &wanted subroutine with the correct commands to mirror that behaviour. For example, your full find command would be something like this:

        find /home/www/*/logs/weekly -exec "gzip {} \| mail me@somewhere \;"

        Try passing that to the find2perl command and you'll get stuff in the &wanted subroutine.

        See the find man page for more details of cool things you can do with find.

        --
        <http://www.dave.org.uk>

        Perl Training in the UK <http://www.iterative-software.com>

Re: Searching a directory tree
by larryk (Friar) on Aug 10, 2001 at 15:53 UTC
    Since you already know the directory structure you don't really need to use find, you can use a glob to get all the files...
    #!/usr/bin/perl -w use strict; for ( </home/www/*/logs/weekly> ) { qx/gzip $_ | mail who@ever.com/; # or however it's done :) }
       larryk                                          
    perl -le "s,,reverse killer,e,y,rifle,lycra,,print"