For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > November 2005 > call ext prog - best way









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author call ext prog - best way
Gary Stainburn

2005-11-24, 6:56 pm

Hi folks

I'm writing a script to be called from exim to allow multiple virus
scanners to be used, and I'm wondering what the best way to do it is.

My script as it stands is below, and I'm using qx{}, to capture the
output, but want to also capture the called program's exit code.

Suggestions welcome on good style and technique.

Gary

#!/bin/perl -w

# called from exim passing a directory name as argument
# calls Sophos Sweep and clamscan on the directory

die "Usage: $0 <message_dir>" unless $ARGV[0];

# cmd - command to call
# viri - result code if virus found
# regex - regex to extract virus lines
my %engines={'sweep'=>{'cmd'=>'/usr/local/bin/sweep -all -rec',
'viri'=>3,
'regex'=>'found'},
'clamscan'=>{'cmd'=>'/usr/bin/clamscan --quiet --stdout -r
--no-summary -i',
'viri'=>1,
'regex'=>'found'}
};

chdir $ARGV[0] || die "$0: cannot chdir: $!\n";

foreach my $engine (%engines) {
my @output=qx{$engine->{'cmd'} .};
# check for result code to indicate success/failure/virus found etc
# if virus, return lines reporting it from @output
# use map/grep/whatever to extract lines.

}
--
Gary Stainburn

This email does not contain private or confidential material as it
may be snooped on by interested government parties for unknown
and undisclosed purposes - Regulation of Investigatory Powers Act, 2000

Jeff 'japhy' Pinyan

2005-11-24, 6:56 pm

On Nov 24, Gary Stainburn said:

> I'm writing a script to be called from exim to allow multiple virus
> scanners to be used, and I'm wondering what the best way to do it is.
>
> My script as it stands is below, and I'm using qx{}, to capture the
> output, but want to also capture the called program's exit code.


The exit code is in the $? variable. You'll need to right-shift it 8
places to get the value you want (see perldoc -f system).

> #!/bin/perl -w


You've got warnings on (albeit via -w instead of 'use warnings'), but
you're not turning strictures on (via 'use strict'). It's strongly
suggested.

> my %engines={'sweep'=>{'cmd'=>'/usr/local/bin/sweep -all -rec',


If you've got warnings turned on, surely you should've seen that you're
assigning a hash REFERENCE to a hash. That is, you're doing:

my %engines = { ... };

where you mean to say

my %engines = ( ... );

You need parentheses there, not curly braces. The OTHER curly braces are
appropriate.

> 'viri'=>3,
> 'regex'=>'found'},


The benefit of using the => operator is that the left-hand side doesn't
need to be quoted if it's a simple bareword.

> 'clamscan'=>{'cmd'=>'/usr/bin/clamscan --quiet --stdout -r
> --no-summary -i',
> 'viri'=>1,
> 'regex'=>'found'}
> };


Which would render:

my %engines = (
sweep => {
cmd => '/usr/local/bin/sweep -all -rec',
viri => 3,
regex => 'found',
},
clamscan => {
cmd => '/usr/bin/clamscan --quiet --stdout -r --no-summary -i',
viri => 1,
regex => 'found',
},
);

> chdir $ARGV[0] || die "$0: cannot chdir: $!\n";


I fear that the || binds too tightly here, and your code is parsed as:

chdir( $ARGV[0] || die "..." );

which means "chdir to either $ARGV[0] or the return value of die(...) if
$ARGV[0] is false". Now, as it turns out, I'm wrong (in this particular
case). But this problem will bite you in other circumstances. Therefore,
to safeguard yourself, either parenthesize specifically, or avoid trouble
by using the loosely-binding 'or' operator:

chdir($ARGV[0]) || die ...;
chdir $ARGV[0] or die ...;

> foreach my $engine (%engines) {


You're looping over the keys AND values of the hash. You mean to say

foreach my $engine (keys %engines) { ... }

> my @output=qx{$engine->{'cmd'} .};
> # check for result code to indicate success/failure/virus found etc
> # if virus, return lines reporting it from @output
> # use map/grep/whatever to extract lines.
> }


That's all I have to say about that.

--
Jeff "japhy" Pinyan % How can we ever be the sold short or
RPI Acacia Brother #734 % the cheated, we who for every service
http://www.perlmonks.org/ % have long ago been overpaid?
http://princeton.pm.org/ % -- Meister Eckhart
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com