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

Ok, I'm a programmer that has been given the task to fix a bug with a Perl-generated web page. I have a background in mainframe programming, and I don't know a thing about Perl so please be gentle.

The page that I'm having trouble with is a query page that greps a particular log file for the a series of strings {tty2, tty3, tty4, ...., tty17} for a given date range.

The code is a loop from 2 - 17 that runs this grep:

$start_ts = sprintf("\"%s %s:%s:00\"",$fromdate,$hr,$min); $end_ts = sprintf("\"%s %s:%s:00\"",$todate,$tohour,$tomin); for ($i = $TTYFIRST; $i <= $TTYLAST; $i++) { Tty_check($i,$start_ts,$end_ts,$selectedserver); } sub Tty_check { $tty_string = sprintf( "tty%d", $_[0] ); $tty = qx{aml_read /l trace /h $_[3] /a commproc /s $_[1] /b $_[2] + /d all | egrep -c -e $tty_string}; printf("<TR ALIGN=LEFT VALIGN=TOP>\n"); printf("<TD>%s</TD>\n",$tty_string); chomp($tty); printf("<TD>%d</TD>\n",$tty); printf("</TR>\n"); }

The query should return a number count for each string search. I've run the line from a UNIX prompt with hardcoded information in the variable names and received correct results. But through the Perl script the program falsely returns 0 as the count or ends abnormally before it can dynamically create the web page (I get a page not found error). Hardcoding the variable information in the Perl script and running it also works. The variables are also displayed and they appear to be correct.

I guess I have 2 questions:

1. Any suggestions on how to debug this?

2. I was hoping to display what that actual query looks like within the qx .... is there a way to write that out to a file or the html page?

Thank you for any help.

Bryan

Replies are listed 'Best First'.
Re: a dumb question
by swiftone (Curate) on Dec 05, 2000 at 01:04 UTC
    I don't know a thing about Perl so please be gentle.

    Okay, I've been somewhat verbose below, ask if you need anything clarified.

    Any suggestions on how to debug this?

    Well, if it is generating a web page, it SHOULD be using the CGI.pm module (Modules are basically libraries). If you see a line like use CGI; near the top of the script, it uses this module. If that is the case, you should be able to run it from the command line, and it will act as if it was called from a browser.

    Of course, if this script is not called from a browser, but instead from a cron job or something like that, and the output redirected to an HTML file, that advice doesn't hold.

    A large problem here is that you are calling egrep without checking for errors. It may well be that egrep isn't in the PATH of the environment that this script is running under.

    I was hoping to display what that actual query looks like within the qx .... is there a way to write that out to a file or the html page?

    I'm not sure what you are asking for here. You can see that the variables correctly interpolated by changing qx{} to qq{} and printing the resulting string, but that doesn't tell you anything about the results of the call itself.

    One second and I'll throw some code to do what I think you're trying to do.

    Update: See my post two below for my later thoughts.

Re: a dumb question
by swiftone (Curate) on Dec 05, 2000 at 01:35 UTC
    Okay, I've poked around with it a bit, and your concern really seems to be whether your quoting characters are being preserved. The following code snippet demonstrates that the quoting is preserved:
    #!/usr/bin/perl -w use strict; my $foo = sprintf("\"|%s\"",'Bar'); print $foo, "\n"; my $bar = qx{echo $foo}; print $bar, "\n";
    (If the quoting wasn't preserved, the | would generate an error)

    So it really looks like it isn't the qx{} that is introducing the error, although it still many not be passing what you expect...Could you show us an example of the expected output?

      I changed the qx to qq and displayed the string as it is built. The result was exactly as I expected. I even cut and paste the generated string on the command prompt and it executed with the expected results. Here is the generated string: aml_read /l trace /h FTWAEIPD0001 /s "12/04/2000 07:00:00" /b "12/04/2000 08:00:00" /d all /appl commproc | egrep -c -e tty2

      ....Which once again should be generated from this:

      $tty = qx{aml_read /l trace /h $_[3] /s $_[1] /b $_[2] /d all /appl c +ommproc | egrep -c -e $tty_string}; printf("<TR ALIGN=LEFT VALIGN=TOP>\n"); printf("<TD>%s</TD>\n",$tty_string); chomp($tty); printf("<TD>%d</TD>\n",$tty); printf("</TR>\n");

      What is also weird is that I can hardcode the variables in the query and get the same results (although it seems to only work outside the loop). I suppose it is possible that I have more than one problem. One problem could be the qx line and the loop may also have errors.

      Thanks Bryan

        What does the output from aml_read look like? Does the web user have permission to run it? Also, it seems a waste to run the command for every tty # when you could tally the results from one run.
        It should also be noted that this problem didn't start occurring until we upgraded the server we are accessing (FTWAEIPD0001) to AIX 4.3.3 ....... in my opinion it is indirectly related to that.

        thanks again, Bryan

Re: a dumb question
by runrig (Abbot) on Dec 05, 2000 at 01:30 UTC
    I would run the script from the command line before testing in a browser window, then printing the input or output of aml_read is simple and might display errors not shown in the browser. That first for loop can be more perlish:
    for my $i ($TTYFIRST..$TTYLAST) { Tty_check($i,$start_ts,$end_ts,$selectedserver); }
    That script doesn't seem well thought out, if you're searching for 'tty1' it'll count lines with 'tty17' also. Depending on the format of the output of that aml_read command (minus the pipe to egrep), I might use perl's split function, so that I could do something like:
    my %ttys; for $line (`aml_read /l trace /h $_[3] /a commproc /s $_[1] /b $_[2] +/d all`) { # I'm making this split up, you'll have to post the # format of aml_read or figure out the split yourself my ($something, $tty, $stuff) = split " ", $line; $ttys{$tty}++; } for my $tty (sort { $a <=> $b} keys %ttys) { print "Count for $tty: $ttys{$_}\n"; }