http://www.perlmonks.org?node_id=940755

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

Hi all Firstly, I'd like to admit that my knowledge in Perl scripting is very low (you can say that I'm dumb) I have been wanting to incorporate wtmp script that i found online into my logwatch script. As it is, when i run the script it gives me the correct output, but when i added that to logwatch the outcome is a string of errors here's the script i am using:
my-mnag0:/etc/logwatch/scripts/services # more my-report perl -we '@type=("Empty","Run Lvl","Boot","New Time","Old Time","Init" +,"Login","Normal","Term","Account");$recs = ""; while (<>) {$r ecs .= $_};foreach (split(/(.{384})/s,$recs)) {next if length($_) == 0 +;my ($type,$pid,$line,$inittab,$user,$host,$t1,$t2,$t3,$t4,$t5 ) = $_ =~/(.{4})(.{4})(.{32})(.{4})(.{32})(.{256})(.{4})(.{4})(.{4})(. +{4})(.{4})/s;if (defined $line && $line =~ /\w/) {$line =~ s/\ x00+//g;$host =~ s/\x00+//g;$user =~ s/\x00+//g;printf("%s %-8s %-12s +%10s %-45s \n",scalar(gmtime(unpack("I4",$t3))),$type[unpack(" I4",$type)],$user,$line,$host)}}printf"\n"' < /var/log/wtmp my-mnag0:/etc/logwatch/scripts/services #
output of the script:
my-mnag0:/etc/logwatch/scripts/services # ./my-report | more Fri Dec 18 22:17:17 2009 Login LOGIN tty1 + Fri Dec 18 22:17:17 2009 Login LOGIN tty2 + Fri Dec 18 22:17:17 2009 Login LOGIN tty3 ...
when the script is used with logwatch this is what i get:
--------------------- wmtp logs Begin ------------------------ String found where operator expected at /etc/logwatch/scripts/service +s/my-report line 1, at end of line (Do you need to predeclare we?) Warning: Use of "log" without parentheses is ambiguous at /etc/logwat +ch/scripts/services/my-report line 1. syntax error at /etc/logwatch/scripts/services/my-report line 1, next + token ??? Search pattern not terminated at /etc/logwatch/scripts/services/my-re +port line 1. ---------------------- wmtp logs End -------------------------
I am not sure what token is meant here because the script runs fine on its own...sorry this must seem dumb to some of you but i am fairly new to Perl. Thank you

Replies are listed 'Best First'.
Re: adding wtmp script into logwatch
by NetWallah (Canon) on Nov 30, 2011 at 04:03 UTC
    It looks like you are invoking your script with 'perl', instead of a shell.

    Since your script starts with 'perl -we', the containing file should be executed by a shell.

    The other option is to get rid the the "perl -we '", and the terminating "'", then let it be invoked by 'perl'.

    FYI - this is what invoking with perl looks like on Windows: (Note the similarity to your messages)

    >perl -e "perl -we 'SomeJunk'" String found where operator expected at -e line 1, near "we 'SomeJunk' +" (Do you need to predeclare we?) syntax error at -e line 1, near "we 'SomeJunk'" Execution of -e aborted due to compilation errors.

                "XML is like violence: if it doesn't solve your problem, use more."

      Hi netwallah I am using bash shell as root user on a suse linux i replaced perl -we with perl but it still gave me error:
      String found where operator expected at /usr/share/logwatch/scripts/s +ervices/my-report line 1, at end of line (Do you need to predeclare perl?) Warning: Use of "log" without parentheses is ambiguous at /usr/share/ +logwatch/scripts/services/my-report line 1. syntax error at /usr/share/logwatch/scripts/services/my-report line 1 +, next token ??? Search pattern not terminated at /usr/share/logwatch/scripts/services +/my-report line 1.
      About the terminating " " which one did u meant? is it this one?
      ;$recs = "";
        What I meant was : Get rid of the "perl -we" entirely.

        This includes the single quotes after "perl -we", and the matching one at the end of the program.

        The reason for this is that , for some reason, for this script, your system is invoking the perl interpreter automatically, instead of the expected bash (or other) shell. And 'perl' does not like a program content to start with 'perl -we'.

                    "XML is like violence: if it doesn't solve your problem, use more."

Re: adding wtmp script into logwatch
by sundialsvc4 (Abbot) on Nov 30, 2011 at 04:20 UTC

    You may certainly assume, here at least, that “your knowledge of Perl scripting is very low” will never be interpreted as “dumb.”   Enjoy...

    Meanwhile ... “one-liners” are funky at times, but it works much better to put the thing into a .pl file.   Because otherwise (as is the case here...) you run smack-dab into the preferences and the peculiarities of whatever shell you happen to be using, with regards to quote-marks and so forth.   With the possible exception of Windows’ so-called “PowerShell,” Windows’s interpretation of what is a decent shell is virtually non-existent.   ahem.   Build a wtmp script that invokes the Perl code by referencing the Perl code in a file.

      hi sundial I did rename the file to a .pl but it didnt work with the logwatch script. i am using a bash shell on suse linux:
      my-mnag0:~ # cat /etc/issue Welcome to SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \r (\l) +.

        That's because you can't copy and paste the entire thing as a .pl file and expect Perl to understand. Here's what you need to have as the contents of the .pl file:

        #!/bin/perl @type = ( "Empty", "Run Lvl", "Boot", "New Time", "Old Time", "Init" +, "Login", "Normal", "Term", "Account" ); $recs = ""; while (<>) { $r ecs .= $_; } foreach ( split( /(.{384})/s, $recs ) ) { next if length($_) == 0 +; my ( $type, $pid, $line, $inittab, $user, $host, $t1, $t2, $t3, $t +4, $t5 ) = $_ =~ /(.{4})(.{4})(.{32})(.{4})(.{32})(.{256})(.{4})(.{4})(.{4} +)(. +{4})(.{4})/s; if ( defined $line && $line =~ /\w/ ) { $line =~ s/\ x00+//g; $host =~ s/\x00+//g; $user =~ s/\x00+//g; printf( "%s %-8s %-12s +%10s %-45s \n", scalar( gmtime( unpack( "I4", $t3 ) ) ), $type[ unpack( " I4", $type ) ], $user, $line, $host ); } } printf "\n"

        The next step after saving your .pl file is to make it executable using the chmod command. A chmod u+x,g+x,o+x wtmp.pl will do it. Then you can run the script like so:

        ./wtmp.pl

        The above assumes that wtmp.pl is in your current directory.