?
Solved

Help in debugging perl code

Posted on 2011-04-27
26
Medium Priority
?
436 Views
Last Modified: 2012-05-11
I have this code snippet that's producing errors:

foreach my $cluster (@clusters){
        open PIPE, "$hi -V $cluster |" or die "pipe open failed: $!";
        my @hosts;
        while (<PIPE>){
                chomp;
                # skip unless line contains type1 or type2
                next unless m{type1|type2};
                # extract the first string (hostname)
                my ($host) = split /\s+/;
                push @hosts, $host;
        }
        close PIPE;
        push @list, @hosts;
}

Open in new window


The error I'm getting is:

Bareword "PIPE" not allowed while "strict subs" in use at collect_du.pl line 39.
Bareword "PIPE" not allowed while "strict subs" in use at collect_du.pl line 49.

If I comment out the 'use strict' pragma which I'd rather not do, then I get this error:

pipe open failed: No such file or directory at ./collect_du.pl line 38.


So basically, the open is failing but I tried different formats like \&PIPE but that didnt work either. I'm not sure how to fix this. Can anyone help?

Any help is appreciated. Thanks.
0
Comment
Question by:akatsuki27
  • 14
  • 6
  • 6
26 Comments
 
LVL 10

Expert Comment

by:jeromee
ID: 35479526
Could you send the whole file?
Also, which version of perl do you use?
Try

# perl -v

This is perl, v5.10.1 (*) built for i686-cygwin-thread-multi-64int
(with 13 registered patches, see perl -V for more detail)

Copyright 1987-2009, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
0
 

Author Comment

by:akatsuki27
ID: 35479548
perl -v

This is perl, v5.8.8 built for x86_64-linux-thread-multi

Copyright 1987-2006, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
0
 
LVL 10

Expert Comment

by:jeromee
ID: 35479597
Thanks.
Could you also send the whole script/file since I don't see anything wrong with the snippet you sent?

.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:akatsuki27
ID: 35479599
This is what I have so far...
#!/usr/bin/perl

use strict;
use warnings;
use lib '/path/to/kerberos/lib/';

use Net::SSH::Perl;
use ITG::Kerberos;
use Sys::Hostname;
use File::Remote qw(:replace);

my $hi = "/path/to/command/bin/hi";
my $user = "akatsuki27";
my @clusters = ("clusterA","clusterB","clusterC","clusterD","clusterE");
my @list;

ITG::Kerberos::init('akatsuki27','/path/to/home/akatsuki27/.keytab') or die 'could not kinit';

#
# Get the list of types 1 and 2
#

foreach my $cluster (@clusters){
        open PIPE, "$hi -V $cluster |" or die "pipe open failed: $!";
        my @hosts;
        while (<PIPE>){
                chomp;
                # skip unless line contains type1or type2
                next unless m{type1 | type2};
                # extract the first string (hostname)
                my ($host) = split /\s+/;
                push @hosts, $host;
        }
        close PIPE;
        push @list, @hosts;
}
@list = sort @list;
# drop last array element which is 'standby' host-- not needed
splice(@list, 54, 1);

#
# Collect the disk usage data from each listed host
#
my $csv = "/path/to/local/csv/file/du_collection.csv";
open (my $csv_fh, '>', $csv) or die "Cannot create <$csv> file $!";

for my $each (@list){
        chomp $each;
        open (my $remote_fh, "$each:/path/to/remote/csv/file/du_out.csv") or
                warn "Cannot open the csv file on $each $!\n" and next;
        <$remote_fh> for (1..3);

        print $csv_fh "*************** $each ***************";

        while (<$remote_fh>){
                print {$csv_fh} $_;
        }
        close $remote_fh;
}
close $csv_fh;

Open in new window

0
 
LVL 10

Assisted Solution

by:jeromee
jeromee earned 800 total points
ID: 35479661
I don't see anything wrong with your script...
The only thing I would try is replacing this:
           open PIPE, "$hi -V $cluster |" or die "pipe open failed: $!";
with

        open(PIPE, "$hi -V $cluster |") or die "pipe open failed: $!";
i.e. adding the ().

How do you run your script?
0
 

Author Comment

by:akatsuki27
ID: 35479686
Well it's going to run from cron once it's complete but right now i'm just executing it from the shell.

Let me try the parentheses and post my results.
0
 
LVL 10

Expert Comment

by:jeromee
ID: 35479700
How do you run it from shell command line?
0
 

Author Comment

by:akatsuki27
ID: 35479703
Still getting compilation errors after adding the parentheses.

Bareword "PIPE" not allowed while "strict subs" in use at collect_du.pl
0
 

Author Comment

by:akatsuki27
ID: 35479705
./collect_du.pl
0
 
LVL 10

Expert Comment

by:jeromee
ID: 35479727
Maybe you can try to add:
     use diagnostics -verbose;
after the use strict; to see what you get.
I can't reproduce the error on my side.

Good luck.
0
 

Author Comment

by:akatsuki27
ID: 35479767
This is part of the message I received.

Execution of ./collect_du.pl aborted due to compilation errors (#1)
    (F) With "strict subs" in use, a bareword is only allowed as a
    subroutine identifier, in curly brackets or to the left of the "=>"
    symbol.  Perhaps you need to predeclare a subroutine?

Can you clarify what it means?
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 35479795
Solution, don't use bareword filehandles.

change:
open PIPE, "$hi -V $cluster |" or die "pipe open failed: $!";

Open in new window


to:
open my $pipe, '-|', "$hi -V $cluster" or die "pipe open failed: $!";

Open in new window


and the other related statements will also need to be changed to use the lexical filehandle
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 35479811
I keep forgetting precedence order, so you may need to add the parens.

open (PIPE, "$hi -V $cluster |") or die "pipe open failed: $!";

Open in new window

0
 

Author Comment

by:akatsuki27
ID: 35479861
I tried the parentheses and was still getting the bareword error. Then I tried your code below and I got this error:

Bad usage of open(HANDLE, file) at ./collect_du.pl line 39


open my $pipe, '-|', "$hi -V $cluster" or die "pipe open failed: $!";

Open in new window

0
 
LVL 28

Expert Comment

by:FishMonger
ID: 35479904
Try it with the parens
open (my $pipe, '-|', "$hi -V $cluster") or die "pipe open failed: $!";

Open in new window


If that still produces an error, then I'd say that your perl installation is broken.  Since 5.8.8 is considered a little on the old side.  The current release is 5.12.3
0
 

Author Comment

by:akatsuki27
ID: 35479928
Yeah I guess it is old then because I'm still seeing the error.
0
 
LVL 10

Expert Comment

by:jeromee
ID: 35480659
I would try another version b/c I'm completely puzzled by that error.
0
 

Author Comment

by:akatsuki27
ID: 35483958
I ran the program through the debugger and I got this message:

Bad usage of open(HANDLE, file) at collect_du.pl line 38
 at /usr/lib/perl5/vendor_perl/5.8.8/File/Remote.pm line 331
      File::Remote::open('undef', '-|', '/path/to/command/bin/hi -V clusterA') called at collect_du.pl line 38
Debugged program terminated.  Use q to quit or R to restart,


It seems to be using the File::Remote module to open the local file and since the format is different, I'm getting the "bad usage" error. Is that a correct assessment?

How can I make it distinguish which is local and which is remote?
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 35484221
Hmm,

I forgot you were using File::Remote, which over rides the default open function.

I haven't tested opening a pipe with that module, but a more robust option for the pipe would be to use one of the IPC modules.

IPC::Run - system() and background procs w/ piping, redirs, ptys (Unix, Win32)
http://search.cpan.org/~toddr/IPC-Run-0.89/lib/IPC/Run.pm

IPC::Open2 - open a process for both reading and writing using open2()
http://search.cpan.org/~rjbs/perl-5.12.3/ext/IPC-Open2/lib/IPC/Open2.pm

IPC::Open3 - open a process for reading, writing, and error handling using open3()
http://search.cpan.org/~rjbs/perl-5.12.3/ext/IPC-Open3/lib/IPC/Open3.pm
0
 

Author Comment

by:akatsuki27
ID: 35485047
Would it sill override it even if it's inside a subroutine?
0
 
LVL 28

Accepted Solution

by:
FishMonger earned 1200 total points
ID: 35485417
Yes it would still be overriden, however there is another option.  Perl's core open function can still be called by specifying the package

CORE::open (my $pipe, '-|', "$hi -V $cluster") or die "pipe open failed: $!";

Open in new window

0
 

Author Comment

by:akatsuki27
ID: 35485874
Nice! That cleared up the error on that line.

Unfortunately, I'm now getting an error on the other open lol...which is actually supposed to be correct.

open (my $csv_fh, '>', $csv) or die "Cannot create <$csv> file $!";

Open in new window


Bad usage of open(HANDLE, file) at collect_du3.pl line 60
 at /usr/lib/perl5/vendor_perl/5.8.8/File/Remote.pm line 331
      File::Remote::open('undef', '>', '/path/to/file/du_collection.csv') called at collect_du3.pl line 60
Debugged program terminated.  Use q to quit or R to restart,
0
 

Author Comment

by:akatsuki27
ID: 35485885
I increased point value since this turned out to be a long question.
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 35486004
After looking at the source code of the module, it looks like File::Remote doesn't support lexical filehandles, which is really dumb/bad.

Looks like you'll need to revert back to using the bareword 'PIPE' filehandle you originally were using.

0
 

Author Comment

by:akatsuki27
ID: 35487095
Sigh...I can't win.

Lexical filehandles I get bad usage errors and barewords I get bareword error:

Bareword "REMOTE" not allowed while "strict subs" in use at collect_du4.pl line 64.
Bareword "REMOTE" not allowed while "strict subs" in use at collect_du4.pl line 73.

I tried using the function-oriented version of File::Remote. This is what the code looks like now:


use File::Remote;

my $remote = new File::Remote;

my $csv = "/path/to/local/file/du_collection.csv";
CORE::open (my $csv_fh, '>', $csv) or die "Cannot create <$csv> file $!";

for my $each (@list){
        chomp $each;
        $remote->open (REMOTE, "$each:/path/to/file/du_out.csv") or warn "Cannot open the csv file on $each $!\n" and next;
        <REMOTE> for (1..3);

        print $csv_fh "*************** $each ***************";

        while (<REMOTE>){
                print {$csv_fh} $_;
        }
        $remote->close (REMOTE);
}
CORE::close $csv_fh;

Open in new window

0
 

Author Comment

by:akatsuki27
ID: 35487370
Finally!! Well, not really...

I finally got rid of the stupid bareword error. I found out that if you add * before the bareword then strict pragma is happy again.

I say not really though because the script is not quite working yet...after running it, I get the warning on each remote file:

Cannot open the csv file on host1.foobar.net No such file or directory
 at collect_du4.pl line 64

The thing is, I know for a fact that the file does exist...
$remote->open (*REMOTE, "$each:/path/to/file/du_out.csv") or warn "Cannot open the csv file on $each $!\n" and next;

Open in new window

0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question