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

Hi all, I have a sticky problem with a bit of code:
open(TMP, "uptime.pl |") or die "$!"; while(<TMP>) { ($receiver,$uptime) = split; push @dataset, $uptime; push @labels, $receiver; } close TMP;
When run from the command line, it works as it should with the @labels and @dataset arrays becoming populated:
70CM 0 50CM 22 H-OH 0 MULTIBEAM 22 GALILEO 0 MULTIBAND 0 METHANOL 22 K-BAND 0
Now when included into a perl/CGI script (versions 5.00404/2.56), the script does not appear to populate the @dataset array:
70CM 0 50CM 0 H-OH 0 MULTIBEAM 0 GALILEO 0 MULTIBAND 0 METHANOL 0 K-BAND 0
ie, the numbers are going to 0. Can anyone help? Regards, Stacy.

Edit kudra, 2001-07-13 Changed title

Replies are listed 'Best First'.
Re: backticks in CGI
by synapse0 (Pilgrim) on Jul 13, 2001 at 09:38 UTC
    The program should die properly if failed to open (unless the pipe fools the call into thinking it went through ok).. but permissions are definitely a factor. Most servers run as "nobody", so you need to make sure that group and other have the permissions you need.
    also, for troubleshooting, you can try:
    while(<TMP>) { ($receiver,$uptime) = split; if ($DEBUG == 'TRUE') { # test split values, make sure you've # printed a header already print "testing: reciever = $reciever : uptime = $uptime<BR>"; } push @dataset, $uptime; push @labels, $receiver; }
    that way you can see what it's doing as it's running..
    remember to print out the vars as it's working if you're not getting what you think you should be..
    -Syn0

    Update: Thinking about the whole user issue, it may be that server user (probably nobody) may not be have access to obtain the information from uptime.pl (it may be able to run the script, but not get the data..)
    just another thought..

      For maderman 's particular problem, I don't think your "debug" print out would tell him anything useful.

      I think I would do

      my $output = `uptime.pl`; # or qx/ / print $output

      or

      my $exit_status = system( "uptime.pl" ); print $exit_status;

      first to make that the uptime.pl script is in fact running

        well.. @lables is being populated, so it looks like the file is being run.. the problem seems to be with the split.. so my method is check what return values from split are...it's just a debugging method to see what's coming from the split.. one step closer to getting it to run..
        -Syn0
      I don't think this is the case: If the main script is getting the @labels array okay, then it should also get @dataset.
Re: backticks in CGI
by lestrrat (Deacon) on Jul 13, 2001 at 09:17 UTC

    you might want to read perlopentut's ( do perldoc perlopentut ) Pipe Open section, which talks about the diffictulties in finding if a command opened through open() failed or not

    I tend to think that since it worked from your command line and not the CGI, the user id for httpd doesn't have the proper permissions or something of that sort.

    My $0.02

Re: backticks in CGI
by Anonymous Monk on Jul 13, 2001 at 11:20 UTC
    Well, despite all your suggestions, I still have failed to get the perl/CGI @dataset array populated as on the command line. Both the main and uptime.pl scripts have 755 set for their permissions. The question regaring the role of split in the code does not appear to be the problem either. For example, with:
    @test = `uptime.pl`; foreach (@test) { print "$_<BR>"; }
    dataset values are still set to 0(ie MULTIBEAM 0). If anyone has the perl gdchart module (http://gdchart.freeservers.com/gdchart/) installed on their system, I'd be happy to send my scripts and see if they work for you. Regards, Stacy.
      Yeah, i should have noticed that in the first place, your arrays are getting populated correctly, but with unexpected data (i.e. your not explicitly setting the 0's, so uptime is returning 0's to you).. so the culprit must be how uptime.pl is running. I don't have the library installed, but I'll take a gander at the code if you'd like (uptime.pl)..
      you can email me at synapsezero@yahoo.com or possibly post it here..
      g'luck either way..
      -Syn0
        Hi all, well I have the problem solved. The script uptime.pl is appended below in it entirety. The problem lies with the @db array (populated by 'more-ing' it). From this array I want $db$i+16 and $db$i+17. From the command line, the program works and I get what I want. But when uptime.pl is accessed from a CGI script, $db$i+16 and $db$i+17 are returning different data and so the script sets @dataset values to '0'. If I change the @db indicies to $db$i+18 and $db$i+19, then I get what I want. Looks like through CGI, I get some extra lines added to the more'd file. Anyway, to avoid this, I have incorporated uptime.pl into the main CGI script (don't know why I didn't do that in the first place!). Thank you all for your help. Regards, Stacy.
        #!/usr/local/bin/perl use Date::Calc qw(Delta_DHMS); @receivers = qw(70CM 50CM H-OH MULTIBEAM GALILEO MULTIBAND METHANOL K-BAND); $dbfile = 'rxdb.dat'; #Get last modify time of DB file rxdb.dat $mtime = (stat("$dbfile"))[9]; ($fsec,$fmin,$fhour,$fmday,$fmonth,$fyear) = localtime($mtime); #Get current time ($nsec,$nmin,$nhour,$nmday,$nmonth,$nyear) = (localtime(time))[0..5]; #Get current time ($nsec,$nmin,$nhour,$nmday,$nmonth,$nyear) = (localtime(time))[0..5]; #Open DB and see if receivers are present and available foreach $package (@receivers) { open(DB, "$dbfile") or die "Can't open $dbfile!: $!"; $i = 0; while ($line = <DB>) { if ($line =~ m/package(\s+)= $package/i) { last } $i++; } close(DB); #$i lists the 'package =' line of the receiver we #want. To determine if it is present and available, #we require 'yes' to be found on lines $i+18 and #$i+19 @db = `more $dbfile`; if ($db[$i+18] =~ m/yes/ && $db[$i+19] =~ m/yes/) { #Selected receiver is present & available. #Calculate difference between file date and current date. ($days, $hours) = Delta_DHMS( $fyear+1900, $fmonth+1, $fmday, $fhour, $fmin, $fsec, $nyear+1900, $nmonth+1, $nmday, $nhour, $nmin, $nsec); $total = sprintf "%3.0f", ($days*24)+$hours; } else { $total = 0; } print "$package $total\n"; }
Re: trouble populating array with input from a file
by MZSanford (Curate) on Jul 13, 2001 at 15:36 UTC
    Just wondering, as this appears to be something with what is printed from uptime.pl, what is uptime.pl doing, and when this works from the command line, are you running as the same user as the CGI would run ?
    My guess is that uptime.pl is doing something not allowed by the user (usually nobody). Usually, if works ok on the command line, but not in CGI it is the diffrence in user access or environment ... so i ould check if uptime.pl uses any of %ENV or external command.
    OH, a sarcasm detector, that’s really useful