Где 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 ...
<<<

Это кажется немного грязным, хотя.

Другие вопросы по тегам