Где pp (PAR) распаковывает add (-a) файлы?
Это моя попытка преодолеть посторонние вопросы: "Почему мои системные вызовы не работают в программе Perl, которую я обертываю с помощью pp?" Я создал простой Perl-скрипт в системе Linux:
new-net:~/scripts # cat ls_test.pl
@ls_out = `ls -l`;
map { print "$_\n" } @ls_out;
$out = `sh out_test.sh`;
print "$out\n";
Этот скрипт вызывает простой файл оболочки:
new-net:~/scripts # cat out_test.sh
echo "I'm here"
Я использовал pp для упаковки скрипта Perl вместе со скриптом оболочки в ls_test:
new-net: ~ / test # unzip -l ls_test Архив: ls_test Длина Дата Время Имя -------- ---- ---- ---- 0 07-13-09 16:41 script/ 436 07-13-09 16:41 МАНИФЕСТ 214 07-13-09 16:41 META.yml 93 07-13-09 16:41 script/ls_test.pl 538 07-13-09 16:41 script/main.pl 16 07-13-09 16:20 out_test.sh -------- ------- 1297 6 файлов
Если я запускаю упакованный файл в пустой директории, сценарий оболочки не найден:
new-net: ~ / test #./ls_test всего 3391 -rwxr-xr-x 1 корневой корень 3466177 13 июля 16:41 ls_test sh: out_test.sh: нет такого файла или каталога
Если я скопирую скрипт оболочки в каталог, упакованный скрипт запустится как положено:
new-net: ~ / test #./ls_test
всего 3395 -rwxr-xr-x 1 корневой корень 3466177 13 июля 16:41 ls_test -rw-r- r-- 1 корневой корень 16 июля 13 16:20 out_test.sh Я здесь
Итак, где же pp
упакованный скрипт ожидаете найти включенный файл? И как настроить вызов этого включенного файла в исходном скрипте Perl?
3 ответа
Файлы в упакованном исполняемом файле извлекаются во временный каталог (обычно /tmp/par-USERNAME/cache-XXXXXXX). Для доступа к этим файлам сделайте что-то вроде следующего:
#!/usr/bin/perl
# Reads a data file from the archive (added with -a)
print PAR::read_file("data");
# Will execute "script2" in the archive and exit. Will not return to this script.
require PAR;
PAR->import( { file => $0, run => 'script2' } );
Вы также можете сделать символические ссылки на исполняемый файл с тем же именем, что и скрипт, который вы хотите запустить, и запустить их.
На самом деле, перечитывая ваш вопрос, просто доступ к переменной окружения PAR_TEMP, вероятно, более полезен:
#!/usr/bin/perl
use File::Slurp qw(slurp);
$data_dir = "$ENV{PAR_TEMP}/inc";
$script_dir = "$data_dir/script";
print slurp("$data_dir/datafile");
# file access permissions are not preserved as far as I can tell,
# so you'll have to invoke the interpreter explicitly.
system 'perl', "$script_dir/script2", @args;
Спасибо всем за участие в этом ответе. Я добавляю этот ответ, чтобы выделить части бесценного вклада каждого, который я использовал, чтобы придумать решение, которое работало для меня в моем конкретном приложении.
Приложение написано на ActiveState Perl с использованием POE и Tk и упаковано для распространения с помощью pp. Оно использует несколько внешних файлов; некоторые для ввода в программу (ложные данные из DNS) и некоторые для действий, предпринимаемых пользователем (создание и удаление записей псевдонимов DNS).
Пакер PAR (pp) включает внешние файлы, используя аргумент -a. Эти файлы распаковываются в каталог \inc по пути "temp", созданному пакетом и доступному сценарию через
$ENV{PAR_TEMP}
Первым шагом в решении было добавить эту информацию в POE "$heap". Строка ниже находится во встроенном состоянии "_start";
$heap->{t_path} = "$ENV{PAR_TEMP}\\inc\\";
Поскольку я работаю в среде Win32, я использовал экранированные обратные слэши, чтобы добавить каталог \inc во временный путь.
При вызове внешнего файла для ввода в приложение я использовал переменную (@zone) для возврата данных;
@zone = `$heap->{t_path}dnscmd aus-dc1 /enumrecords company.pvt @`;
Для вызовов для выполнения внешних действий файлы вызываются без сохранения вывода;
`$heap->{t_path}cpau -dec -file $heap->{t_path}del_event.job -nowarn -wait`;
Еще раз спасибо всем за участие и спасибо stackru за предоставление этой великолепной среды.
Вот что работает в моей системе:
C: \ tmp> cat build.bat @ эхо выключено вывод mkdir вызовите pp -o runner.exe runner.pl -a sayhello.bat переместить вывод runner.exe \ runner.exe
C: \ tmp> cat sayhello.bat @ эхо я говорю привет...
C:\tmp> cat runner.pl
#!/usr/bin/perl
use strict;
use warnings;
use File::Spec::Functions qw( catfile );
my $prog_path = catfile $ENV{PAR_TEMP}, inc => 'sayhello.bat';
my $output = `$prog_path`;
print "The output was: >>> $output <<< ";
__END__
Выход:
C:\tmp\output> runner.exe
The output was: >>> I am saying hello ...
<<<
Это кажется немного грязным, хотя.