Хорошо, несколько правил:
- Нет, я не могу установить Strawberry Perl в этой системе. Я должен использовать Cygwin.
- Это Perl 5.8.7. Я не могу обновить его.
- Это не моя система. Это система заказчика, и я не могу модифицировать ее по своему усмотрению.
Теперь мы избавились от этого...
Я установил Spreadsheet::Read
, Spreadsheet::ParseExcel
и Spreadsheet::XLSX
в этой системе. Это установило небольшой Perl-скрипт под названием xlscat
. Мы делали это раньше на блоке разработки и блоке UAT. Теперь это производственная коробка.
Я получаю следующую ошибку:
Parser for XLSX is not installed at /usr/bin/xlscat line 185
Я проследил это до Spreadsheet::Read
. Соответствующий код:
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:
Строки, которые начинаются со строки DEBUG:
, принадлежат мне.
Дамп @parsers
показывает, что все загружается корректно. Первая отладка правильно выводит значения $flag
и $mod
.
Проблема, похоже, связана с оператором eval
. Из того, что я вижу, он запускает require
для модуля, а затем устанавливает переменную $can{$flag}
в $mod
, если запрос выполнен успешно. Судя по всему, require Spreadsheet::XLSX
не работает. Вот соответствующий вывод из моих операторов отладки:
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
};
Хммм... Может модуль не установлен?
$ perldoc -l Spreadsheet::XLSX
/usr/lib/perl5/site_perl/5.8/Spreadsheet/XLSX.pm
Он появляется в perldoc
. Давайте напишем быструю тестовую программу:
#! /usr/bin/env perl
use Spreadsheet::Read;
use Spreadsheet::XLSX;
print "It works\n";
И...
$ ./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
Я могу подобрать Spreadsheet::XLSX
через use Spreadsheet::XLSX
в моей тестовой программе, но require
в Spreadsheet::Read
, похоже, его не видит.
Почему?
Приложение
Что вы получите, если напечатаете Dumper(\%INC)? - Фридо 2 минуты назад
Я на самом деле сделал один лучше. Я добавил в цикл следующую строку:
require $mod if ($mod eq "Spreadsheet::XLSX"); #DEBUG
И это вызвало сообщение об ошибке:
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.
(ПРИМЕЧАНИЕ: я переформатировал выходные данные, чтобы они не превышали 1000 символов, и было легче увидеть путь @INC
).
Модуль находится в /usr/lib/perl5/site_perl/5.8/Spreadsheet/XLSX.pm
.
О, взгляните и на это:
$ 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
Разрешения вроде в порядке.
Еще одно дополнение:
Когда я сделал переустановку CPAN, я получил это:
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
Ой! Я не проверял разрешение дерева каталогов /usr/lib/perl5/site_perl/5.8/cygwin
.
Сделал chmod -R a+rx *
для всего каталога /usr/lib/perl5
. Посмотрим, сработает ли снова.
print Dumper( \%INC )
? - person friedo   schedule 02.11.2011@INC
в порядке, как и права доступа к файлам. - person David W.   schedule 02.11.2011require $mod
делает не то, что вы думаете. См.perldoc -f require
. Вам нужноeval "require $mod"
- person Sinan Ünür   schedule 02.11.2011$@
после оператораeval "require $mod ..."
? - person mob   schedule 02.11.2011eval "$require $mod
?Spreadsheet::Read
уже выполняет оценку. Я сделал это безeval
, поэтому я вижу ошибку. - person David W.   schedule 02.11.2011cpan
и посмотреть, исчезнет ли проблема. Если у меня возникнут те же проблемы, я проверю значение как@INC
, так и%INC
. - person David W.   schedule 02.11.2011$mod
содержит строкуSpreadsheet::XLSX
, тоrequire $mod
ищет файлSpreadsheet::XLSX
, а неSpreadsheet/XLSX.pm
. Вот почему вам нужноeval "require $mod"
. - person Sinan Ünür   schedule 02.11.2011@INC
. Я делаю переустановку и смотрю, что происходит. Если это не сработает, я изменю этот оператор, чтобы удалить$mod
и сделать прямоеrequire Spreadsheet::XLSX
. - person David W.   schedule 02.11.2011