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

Hi,

I am running this code in the command line. I am getting the output, But it also display a message like this :

Usage: grep [OPTION]... PATTERN [FILE]... Try `grep --help' for more information. cure1: "|/usr/local/sbin/vandos.pl /var/vandos/cure1.msg cure1@ww +w.usamarinestore.com", \cure1 sur: forward@ths.com
Please go through my code and provide a solution.
#!/usr/bin/perl $arg1 = $ARGV[0]; @filelist = ` find /home/sites/$arg1/users -type d `; chomp @filelist; @store = (); foreach $fle(@filelist) { ($junk, $reqd )=split (/\/users\//,$fle); ($reqd, $junk) = split (/\//,$reqd); push (@store,$reqd); } foreach(@store) { print `cat /etc/mail/aliases | grep $_`; }
Thanks

20030214 Edit by Corion: Added formatting, changed title

Replies are listed 'Best First'.
On Useless Cats
by merlyn (Sage) on Feb 14, 2003 at 13:30 UTC
    At the time I write this, the question and all answers have a Useless Use of Cat. And that's actually complicating the solutions. If you get rid of the unneeded pipe, you can switch to a multi-arg system call, and then you can pass a string without worrying about what it contains:
    system "grep", "-e", $_, "/etc/mail/aliases";
    And in this case, it saves not one process, but two!

    Beware the useless use of cat.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.


    update: updated URL per notice.

      Useless Use of Cat.
      Redirecting to http://www.iki.fi/era/unix/award.html. Follow the link if this message remains visible.
       
      I told people to not bookmark files on this server. You have my permission to be rude when you point this out to the owner of the referring page. Thank you.

      ;-)
      don't know how to be rude, though

      regards,
      tomte


Re: Error in converted shell script (was: Pls Help)
by mugwumpjism (Hermit) on Feb 14, 2003 at 13:09 UTC

    Porting Shell to Perl must be done mindfully of simpler ways to achieve the same thing. It is ineffective to use `cat | grep` multiple times, when you could simply read the file in and print out the lines that you are interested in one by one.

    For example; and this will still not quite do what you want, which is no doubt to retrieve all active aliases entries for a given site. You will also need to consider /etc/mail/virtusertable if present on your system.

    #!/usr/bin/perl -w use strict; use constant MAIL_ALIASES => "/etc/mail/aliases"; my $site = shift; # all users of a site have home directories under # /home/sites/XXX/users/. my @users = (map { m{/([^/]*)$} } # `basename' with a RE (grep { -d $_ } # only directories </home/sites/$site/users/*> # glob )); # build a big regular expression with each user name; # use \b to anchor the pattern match, so that a user called # `jane' won't show up entries for `janet' my $pattern = '\b(' . join("|", @users) . ')\b'; open ALIASES, MAIL_ALIASES or die("Failed to open ".MAIL_ALIASES."; $!"); while (<ALIASES>) { print if m/$pattern/o; } close ALIASES;
Re: Error in converted shell script (was: Pls Help)
by Tomte (Priest) on Feb 14, 2003 at 13:04 UTC

    I bet that here

    print `cat /etc/mail/aliases | grep $_`;
    you want to say:
    print `cat /etc/mail/aliases | grep "$_"`;
    or
    print `cat /etc/mail/aliases | grep '$_'`;
    And I daresay you're having some quirky user/dir-names :-) (spaces would suffice to break the grep-call) To be sure you should supply the list of subdirectory-names your greping for.

    hth
    regards,
    tomte


Re: Error in converted shell script (was: Pls Help)
by castaway (Parson) on Feb 14, 2003 at 12:51 UTC
    One solution:
    To throw away any error output from grep that you don't want, change your last-but-one line to:
    print `cat /etc/mail/aliases | grep $_ 2>/dev/null`;
    Though you should probably find out whats actually causing the error, and fix that instead.

    C.

      The script calls grep without arguments one time, because @filelist includes '/home/sites/$arg1/users'. A correct solution would be to call find with appropriate arguments: find <path> -type d -mindepth 1 -maxdepth 1. This command simplifies also the script, because you don't need to munge @filelist, and doesn't overload system issuing repeated deep scans of file system.

      Ciao, Valerio

      Thanks a lot. It's working properly. Before that i solved using shift(@store) statement. But your answer is exactly i needed. Best Regards
Re: Error in converted shell script (was: Pls Help)
by jacques (Priest) on Feb 14, 2003 at 14:12 UTC
    Merlyn is right, but you may also want to check the return value on the system call.

    system("grep -i $_ /etc/mail/aliases") == 0 or die "grep program failed";