Где pp (PAR) распаковывает add (-a) файлы? - PullRequest
6 голосов
/ 14 июля 2009

Это моя попытка преодолеть возникшие посторонние проблемы «Почему мои системные вызовы не работают в программе 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
Archive:  ls_test
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  07-13-09 16:41   script/
      436  07-13-09 16:41   MANIFEST
      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 files

Если я запускаю упакованный файл в пустой директории, сценарий оболочки не будет найден:

new-net:~/test # ./ls_test
total 3391

-rwxr-xr-x 1 root root 3466177 Jul 13 16:41 ls_test

sh: out_test.sh: No such file or directory

Если я скопирую скрипт оболочки в каталог, упакованный скрипт запустится, как и ожидалось:

new-net:~/test # ./ls_test<br>
total 3395

-rwxr-xr-x 1 root root 3466177 Jul 13 16:41 ls_test
-rw-r--r-- 1 root root      16 Jul 13 16:20 out_test.sh

I'm here

Итак, где упакованный скрипт pp ожидает найти включенный файл? И как настроить вызов этого включенного файла в исходном скрипте Perl?

Ответы [ 3 ]

6 голосов
/ 14 июля 2009

Файлы упакованного исполняемого файла извлекаются во временный каталог (обычно / 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;
4 голосов
/ 15 июля 2009

Спасибо всем за участие в этом ответе. Я добавляю этот ответ, чтобы вычленить части бесценного вклада каждого, который я использовал, чтобы придумать решение, которое работало для меня в моем конкретном приложении.

Приложение написано на ActiveState Perl с использованием POE и Tk и упаковано для распространения с помощью стр. Оно использует несколько внешних файлов; некоторые для ввода в программу (ложные данные из 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`;

Еще раз спасибо всем за участие и спасибо stackoverflow за предоставление этой великолепной среды.

3 голосов
/ 14 июля 2009

Вот что работает в моей системе:

C:\tmp> cat build.bat
@echo off
mkdir output
call pp -o runner.exe runner.pl -a sayhello.bat
move runner.exe output\runner.exe
C:\tmp> cat sayhello.bat
@echo I am saying hello ...

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 ...
<<<

Хотя это немного грязно.

...