Okay a few rules:
Now, we've gotten that out of the way...
I have installed Spreadsheet::Read
, Spreadsheet::ParseExcel
, and Spreadsheet::XLSX
on this system. This installed a little Perl script called xlscat
. We've done this before on a development box and the UAT box. Now this is the production box.
I am getting the following error:
Parser for XLSX is not installed at /usr/bin/xlscat line 185
I've traced this to Spreadsheet::Read
. The relevant code is:
my @parsers = (
[ csv => "Text::CSV_XS" ],
[ csv => "Text::CSV_PP" ], # Version 1.05 and up
[ csv => "Text::CSV" ], # Version 1.00 and up
[ ods => "Spreadsheet::ReadSXC" ],
[ sxc => "Spreadsheet::ReadSXC" ],
[ xls => "Spreadsheet::ParseExcel" ],
[ xlsx => "Spreadsheet::XLSX" ],
[ prl => "Spreadsheet::Perl" ],
# Helper modules
[ ios => "IO::Scalar" ],
);
my %can = map { $_->[0] => 0 } @parsers;
for (@parsers) {
my ($flag, $mod) = @$_;
print STDERR qq(DEBUG: Flag = "$flag" Mod = "$mod"\n);
$can{$flag} and next;
eval "require $mod; \$can{\$flag} = '$mod'";
}
print STDERR Dumper(\%can); #DEBUG:
The lines that start contain the string DEBUG:
are mine.
A dump of @parsers
shows that everything is loaded correctly. The first debug prints out the value of $flag
and $mod
correctly.
The problem seems to come from the eval
statement. From what I can see, it runs require
against a module, and then sets the $can{$flag}
variable to $mod
if the require succeeds. Apparently, require Spreadsheet::XLSX
fails. Here's the relevant output from my debug statements:
DEBUG: Flag = "csv" Mod = "Text::CSV_XS"
DEBUG: Flag = "csv" Mod = "Text::CSV_PP"
DEBUG: Flag = "csv" Mod = "Text::CSV"
DEBUG: Flag = "ods" Mod = "Spreadsheet::ReadSXC"
DEBUG: Flag = "sxc" Mod = "Spreadsheet::ReadSXC"
DEBUG: Flag = "xls" Mod = "Spreadsheet::ParseExcel"
DEBUG: Flag = "xlsx" Mod = "Spreadsheet::XLSX"
DEBUG: Flag = "prl" Mod = "Spreadsheet::Perl"
DEBUG: Flag = "ios" Mod = "IO::Scalar"
$VAR1 = {
'csv' => 'Text::CSV_XS',
'sxc' => 0,
'xlsx' => 0,
'xls' => 'Spreadsheet::ParseExcel',
'ios' => 'IO::Scalar',
'prl' => 0,
'ods' => 0
};
Hmmm... Maybe the module isn't installed?
$ perldoc -l Spreadsheet::XLSX
/usr/lib/perl5/site_perl/5.8/Spreadsheet/XLSX.pm
It shows up in perldoc
. Let's write a quick test program:
#! /usr/bin/env perl
use Spreadsheet::Read;
use Spreadsheet::XLSX;
print "It works\n";
And...
$ ./test.pl
DEBUG: Flag = "csv" Mod = "Text::CSV_XS"
DEBUG: Flag = "csv" Mod = "Text::CSV_PP"
DEBUG: Flag = "csv" Mod = "Text::CSV"
DEBUG: Flag = "ods" Mod = "Spreadsheet::ReadSXC"
DEBUG: Flag = "sxc" Mod = "Spreadsheet::ReadSXC"
DEBUG: Flag = "xls" Mod = "Spreadsheet::ParseExcel"
DEBUG: Flag = "xlsx" Mod = "Spreadsheet::XLSX"
DEBUG: Flag = "prl" Mod = "Spreadsheet::Perl"
DEBUG: Flag = "ios" Mod = "IO::Scalar"
$VAR1 = {
'csv' => 'Text::CSV_XS',
'sxc' => 0,
'xlsx' => 0,
'xls' => 'Spreadsheet::ParseExcel',
'ios' => 'IO::Scalar',
'prl' => 0,
'ods' => 0
};
It works
I can pick up Spreadsheet::XLSX
via the use Spreadsheet::XLSX
in my test program, yet the require
in Spreadsheet::Read
doesn't seem to see it.
Why?
What do you get if you print Dumper( \%INC ) ? – friedo 2 mins ago
I actually did one better. I added the following line in the loop:
require $mod if ($mod eq "Spreadsheet::XLSX"); #DEBUG
And that produced the error message:
Can't locate Spreadsheet::XLSX in @INC (@INC contains:
/usr/lib/perl5/5.8/cygwin /usr/lib/perl5/5.8
/usr/lib/perl5/site_perl/5.8/cygwin
/usr/lib/perl5/site_perl/5.8
/usr/lib/perl5/site_perl/5.8/cygwin
/usr/lib/perl5/site_perl/5.8
/usr/lib/perl5/vendor_perl/5.8/cygwin
/usr/lib/perl5/vendor_perl/5.8
/usr/lib/perl5/vendor_perl/5.8/cygwin
/usr/lib/perl5/vendor_perl/5.8 .) at
/usr/lib/perl5/site_perl/5.8/Spreadsheet/Read.pm line 57.
Compilation failed in require at ./test.pl line 3.
BEGIN failed--compilation aborted at ./test.pl line 3.
(NOTE: I reformatted the output, so it wouldn't be 1000+ characters long, and it's easier to see the @INC
path).
The module is in /usr/lib/perl5/site_perl/5.8/Spreadsheet/XLSX.pm
.
Oh, take a look at this too:
$ pwd
/usr/lib/perl5/site_perl/5.8/Spreadsheet
$ ls -la
total 152
drwxr-xr-x+ 4 phalder Domain Users 0 Nov 1 21:51 .
drwxrwxrw-+ 11 twinborne Users 0 Nov 1 22:28 ..
drwxr-xr-x+ 3 phalder Domain Users 0 Nov 1 20:48 ParseExcel
-rwxr-xr-x 1 phalder Domain Users 107773 Apr 6 2011 ParseExcel.pm
-rwxrwxrwx 1 phalder Domain Users 29142 Nov 2 12:53 Read.pm
drwxr-xr-x+ 2 phalder Domain Users 0 Nov 1 21:51 XLSX
-rwxr-xr-x 1 phalder Domain Users 8411 May 16 2010 XLSX.pm
$ ls -la XLSX
total 48
drwxr-xr-x+ 2 phalder Domain Users 0 Nov 1 21:51 .
drwxr-xr-x+ 4 phalder Domain Users 0 Nov 1 21:51 ..
-rwxr-xr-x 1 phalder Domain Users 5487 May 16 2010 Fmt2007.pm
-rwxr-xr-x 1 phalder Domain Users 37046 May 16 2010 Utility2007.pm
The permissions seem okay.
When I did a CPAN reinstall, I got this:
Result: PASS
/usr/bin/make test -- OK
Running make install
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ERROR: Can't create '/usr/lib/perl5/site_perl/5.8/cygwin/auto/Spreadsheet/Read'
Do not have write permissions on
'/usr/lib/perl5/site_perl/5.8/cygwin/auto/Spreadsheet/Read'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
at -e line 1
Installing /usr/lib/perl5/site_perl/5.8/Spreadsheet/Read.pm
Installing /usr/share/man/man3/Spreadsheet.Read.3pm
make: *** [pure_site_install] Error 255
/usr/bin/make install -- NOT OK
Oops! I didn't check the permission of the /usr/lib/perl5/site_perl/5.8/cygwin
directory tree.
Did a chmod -R a+rx *
on the whole /usr/lib/perl5
directory. We'll see if it works again.
I took a slightly different tact. I modified Spreadsheet::Read
to print out $@
after the eval
. That way, I could see what error it was getting. Here's the results:
$ ./test.pl
DEBUG: ""DEBUG: "Can't locate Spreadsheet/ReadSXC.pm in @INC
(@INC contains:
/usr/lib/perl5/5.8/cygwin
/usr/lib/perl5/5.8
/usr/lib/perl5/site_perl/5.8/cygwin
/usr/lib/perl5/site_perl/5.8
/usr/lib/perl5/site_perl/5.8/cygwin
/usr/lib/perl5/site_perl/5.8
/usr/lib/perl5/vendor_perl/5.8/cygwin
/usr/lib/perl5/vendor_perl/5.8
/usr/lib/perl5/vendor_perl/5.8/cygwin
/usr/lib/perl5/vendor_perl/5.8 .) at (eval 8) line 1.
"DEBUG: "Can't locate Spreadsheet/ReadSXC.pm in @INC
(@INC contains: /usr/lib/perl5/5.8/cygwin [...]) at (eval 9) line 1.
"DEBUG: ""DEBUG: "Can't locate Compress/Raw/Zlib.pm in @INC
(@INC contains: /usr/lib/perl5/5.8/cygwin [...]) at (eval 15) line 1.
"DEBUG: "Can't locate Spreadsheet/Perl.pm in @INC
(@INC contains: /usr/lib/perl5/5.8/cygwin [...]) at (eval 18) line 1.
Did you see that? The problem isn't Spreadsheet::XLSX
, but Compress::Raw::Zlib
. I set the entire permissions on /usr/lib/perl
to 777
, and then installed Compress::Raw::Zlib
and Spreadsheet::ReadSXC
.
This must have been a problem when these modules were initially installed. I wasn't the one doing the cpan install, but helping the person over the phone, so I didn't get a chance to see these errors if they popped up. CPAN tends to be really, really noisy, and I've learned to catch the random error message as CPAN runs by.
The problem may have been /usr/lib/perl5/site_perl/5.8/cygwin
not having the correct permissions all along.
The program now works.
Thanks for all of your help. Somehow, it lead me down the right trail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With