teamassociated has asked for the wisdom of the Perl Monks concerning the following question:
I am failing to get this working for a day now. Looked at URL : https://stackoverflow.com/questions/6845376/how-to-pass-a-file-handle-to-a-function
but no go.
I am passing an array of paths+files like so "/opt/r2configs/.../lparstat-i.out" as a reference into a sub. When I try to open these, it fails.
use strict;
use warnings;
my %seen = ();
my $flag = 0;
my (@nonprod_lpars, @lparstat, $clntdir);
my $regexp_2_skip = qr/entitled capacity of pool/i;
my $regexp_2_get = qr/entitled capacity|desired Virtual CPU|desired M
+emory|online Virtual CPU|maximum Virtual CPU|maximum memory|online me
+mory/i;
my $datacsv = qq($basedir/nonprod_resource_stats_4_mgmt.csv);
open (my $csv, ">>$datacsv") or die "failed to open $datacsv $!\n";
sub _ce {
print "IN CE SUB\n";
die "no parameter!\n" unless @_;
my ($ce_ref) = @_;
for my $name (@{ $ce_ref }) {
@asof = +(split("/", $name, 0))[-3,-2,-4];
$lpname = +(split("/", $name, 0))[3];
print $csv "$lpname\n";
print $csv '*' x length($lpname),"\n";
print '*' x length($lpname),"\n";
print "$name\n";
open (my $i, "+<", $name) or warn $!; ### FAILS HERE ###
while (<$i>) {
chomp $i;
next if $i =~ /$regexp_2_skip/;
next if $i !~ /$regexp_2_get/;
($i) =~ s/:/,/g;
($i) =~ s/\s+//g;
print $csv "$i,\n";
print "$i,\n";
}
}
print $csv "\n\nHost,Entitled CPU and RAM as of @asof,\n\n";
return;
}
...
...
print "heading into lparstat find $clntdir count of nonprodlpars", sca
+lar @nonprod_lpars;
for my $npll (@nonprod_lpars) {
next if $npll =~ /null/i;
print "\nnpll: $npll";
push @lparstat, qx(/usr/bin/find "$clntdir/$npll" -name $lparstout
+ -mtime 1);
print " lparstat count:", scalar @lparstat;
}
if ( scalar @nonprod_lpars == scalar @lparstat ) {
$flag = 1;
print "\nFLAG:$flag\n";
_ce( \@lparstat );
}
else {
print "at top of mtime 2 block\n";
print "SCALAR NPLPARS ",scalar @nonprod_lpars;
for my $npll (@nonprod_lpars) {
next if $npll =~ /null/i;
push @lparstat, qx(/usr/bin/find "$clntdir/$npll" -name $lpars
+tout -mtime 2);
}
print "SCALAR lparstat: ", scalar @lparstat;
if ( scalar @nonprod_lpars == scalar @lparstat ) {
$flag = 2;
_ce( \@lparstat );
}
.
.
.
__OUT__
$name is clearly getting passed ok from my prints:
No such file or directory at get_nonprod_AIX_resrcs_used.plx line 456.
readline() on closed filehandle $i at get_nonprod_AIX_resrcs_used.plx
+line 457.
************
/opt/r2configs/twcsapcont01/2018/03/13/lparstat-i.out
and a confirmation it does exist is here
# ls -l /opt/r2configs/twcsapcont01/2018/03/13/lparstat-i.out
-rw-r--r-- 1 root system 2225 Mar 13 21:16 /opt/r2confi
+gs/twcsapcont01/2018/03/13/lparstat-i.out
thank you!
Re: opening a file passed into sub as ref
by Corion (Patriarch) on Mar 15, 2018 at 17:51 UTC
|
The code you show can't be the code you're running.
A reduced version of your code dies with an error for me:
use strict;
use warnings;
my %seen = ();
my $flag = 0;
my (@nonprod_lpars, @lparstat, $clntdir);
my $regexp_2_skip = qr/entitled capacity of pool/i;
my $regexp_2_get = qr/entitled capacity|desired Virtual CPU|desired M
+emory|online Virtual CPU|maximum Virtual CPU|maximum memory|online me
+mory/i;
my @asof;
sub _ce {
print "IN CE SUB\n";
die "no parameter!\n" unless @_;
my ($ce_ref) = @_;
for my $name (@{ $ce_ref }) {
#@asof = +(split("/", $name, 0))[-3,-2,-4];
#$lpname = +(split("/", $name, 0))[3];
#print $csv "$lpname\n";
#print $csv '*' x length($lpname),"\n";
#print '*' x length($lpname),"\n";
print "$name\n";
open (my $i, "+<", $$name) or warn $!; ### FAILS HERE ###
while (<$i>) {
chomp $i;
next if $i =~ /$regexp_2_skip/;
next if $i !~ /$regexp_2_get/;
($i) =~ s/:/,/g;
($i) =~ s/\s+//g;
#print $csv "$i,\n";
print "$i,\n";
}
}
#print $csv "\n\nHost,Entitled CPU and RAM as of,\n\n";
return;
}
@lparstat = ('1','2','3');
_ce(\@lparstat);
Either you slapped use strict; at the top of your program without re-running it, or you are running other code than the code you are looking at.
Running your program with use strict; immediately lets Perl tell you what goes wrong. Another hint would be to actually print the filename you're trying to open:
open (my $i, "+<", $$name) or warn "Failed to open '$$name': $
+!"; ### FAILS HERE ###
If you're not using strict, Perl will allow you to dereference things that are not a reference. This rarely makes sense but you will actually see the contents of $$name (nothing).
Maybe that is just a typo and you wanted to use $name instead. | [reply] [d/l] [select] |
|
the correct code is yes w/out $$name rather using $name
i always use strict and warnings. its there in the code at the top.
sub _ce {
print "IN CE SUB\n";
die "no parameter!\n" unless @_;
my ($ce_ref) = @_;
for my $name (@{ $ce_ref }) {
@asof = +(split("/", $name, 0))[-3,-2,-4];
$lpname = +(split("/", $name, 0))[3];
print $csv "$lpname\n";
print $csv '*' x length($lpname),"\n";
print '*' x length($lpname),"\n";
print "$name\n";
open (my $i, "+<", $name) or warn $!; ### FAILS HERE ###
while (<$i>) {
chomp $i;
next if $i =~ /$regexp_2_skip/;
next if $i !~ /$regexp_2_get/;
($i) =~ s/:/,/g;
($i) =~ s/\s+//g;
print $csv "$i,\n";
print "$i,\n";
}
}
print $csv "\n\nHost,Entitled CPU and RAM as of @asof,\n\n";
return;
}
__OUT__
SCALAR NPLPARS 30 SCALAR lparstat: 30
IN CE SUB
********
/opt/r2configs/edidev00/2018/03/13/lparstat-i.out
No such file or directory at get_nonprod_AIX_resrcs_used.plx line 454,
+ <$lus> line 131.
readline() on closed filehandle $i at get_nonprod_AIX_resrcs_used.plx
+line 455.
**********
/opt/r2configs/ediperqa00/2018/03/13/lparstat-i.out
# ls -l /opt/r2configs/ediperqa00/2018/03/13/lparstat-i.out
-rw-r--r-- 1 root system 2219 Mar 13 21:00 /opt/r2confi
+gs/ediperqa00/2018/03/13/lparstat-i.out
| [reply] [d/l] |
|
open (my $i, "+<", $name) or warn $!; ### FAILS HERE ###
while (<$i>) {
chomp $i;
next if $i =~ /$regexp_2_skip/;
next if $i !~ /$regexp_2_get/;
($i) =~ s/:/,/g;
($i) =~ s/\s+//g;
print $csv "$i,\n";
print "$i,\n";
}
as Toolic said, you probably have line endings on $name from find. Try
sub _ce {
print "IN CE SUB\n";
die "no parameter!\n" unless @_;
my ($ce_ref) = @_;
for my $name (@{ $ce_ref }) {
chomp $name;
@asof = +(split("/", $name, 0))[-3,-2,-4];
$lpname = +(split("/", $name, 0))[3];
print $csv "$lpname\n";
print $csv '*' x length($lpname),"\n";
print '*' x length($lpname),"\n";
print "$name\n";
open (my $fh, "+<", $name) or die "Could not open '$name' $!";
+ ### FAILS HERE ###
while (my $line = <$fh>) {
chomp $line;
next if $line =~ /$regexp_2_skip/;
next if $line !~ /$regexp_2_get/;
$line =~ s/:/,/g;
$line =~ s/\s+//g;
print $csv "$line,\n";
print "$line,\n";
}
}
print $csv "\n\nHost,Entitled CPU and RAM as of @asof,\n\n";
return;
}
poj | [reply] [d/l] [select] |
Re: opening a file passed into sub as ref
by toolic (Bishop) on Mar 15, 2018 at 17:47 UTC
|
chomp @lparstat;
| [reply] [d/l] |
Re: opening a file passed into sub as ref
by jwkrahn (Abbot) on Mar 15, 2018 at 18:54 UTC
|
print $csv "$lpname\n";
print $csv '*' x length($lpname),"\n";
print $csv "$i,\n";
print $csv "\n\nHost,Entitled CPU and RAM as of @asof,\n\n";
$csv is not a valid FILEHANDLE. It has not been opened anywhere so it cannot be printed to.
open (my $i, "+<", $name) or warn $!; ### FAILS HERE ###
while (<$i>) {
chomp $i;
next if $i =~ /$regexp_2_skip/;
next if $i !~ /$regexp_2_get/;
($i) =~ s/:/,/g;
($i) =~ s/\s+//g;
print $csv "$i,\n";
print "$i,\n";
}
The variable $i is first used as a FILEHANDLE and then used as text from a file.
But in the line while (<$i>) { you are assigning the file text to the variable $_ which you don't use at all.
| [reply] [d/l] [select] |
|
apologies, csv is opened in the code. i forgot to paste it. the error says $i and $i is not being opened that csv FH.
| [reply] |
|
|