Où pp (PAR) décompresse-t-il les fichiers (-a)?

C’est ma tentative de résoudre les problèmes supplémentaires soulevés “Pourquoi les appels système ne fonctionnent-ils pas dans le programme Perl que j’emballe avec pp?” J’ai créé un simple script Perl sur un système 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"; 

Ce script appelle un fichier shell simple:

 new-net:~/scripts # cat out_test.sh echo "I'm here" 

J’ai utilisé pp pour emballer le script Perl avec le script shell dans ls_test:

 new-net: ~ / test # unzip -l ls_test
 Archive: ls_test
   Longueur Date Heure Nom
  -------- ---- ---- ----
         0 07-13-09 16:41 script /
       436 07-13-09 16:41 MANIFESTE
       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 fichiers

Si je lance le fichier compressé dans un répertoire vide, le script shell est introuvable:

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

 -rwxr-xr-x 1 racine racine 3466177 13 juillet 16:41 ls_test

 sh: out_test.sh: Pas de tel fichier ou répertoire

Si je copie le script shell dans le répertoire, le script compressé s’exécute comme prévu:

 new-net: ~ / test # ./ls_test 
total 3395 -rwxr-xr-x 1 racine racine 3466177 13 juillet 16:41 ls_test -rw-r - r-- 1 racine racine 16 juil. 13 16:20 out_test.sh je suis ici

Alors, où un script de paquetage pp espère-t-il trouver un fichier inclus? Et comment un appel à ce fichier inclus devrait-il être configuré dans le script Perl d’origine?

Les fichiers d’un exécutable empaqueté sont extraits dans un répertoire temporaire (généralement / tmp / par-USERNAME / cache-XXXXXXX). Pour accéder à ces fichiers, procédez comme suit:

 #!/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' } ); 

Vous pouvez également créer des liens sympas vers l’exécutable qui porte le même nom que le script que vous souhaitez exécuter et les exécuter.

En fait, en relisant votre question, accéder simplement à la variable d’environnement PAR_TEMP est probablement plus utile:

 #!/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; 

Merci à tous d’avoir consortingbué à cette réponse. J’ajoute cette réponse pour faire ressortir les parties de la consortingbution inestimable de tout le monde que j’avais l’habitude de trouver avec la solution qui fonctionnait pour moi dans mon application particulière.

L’application est écrite en ActiveState Perl en utilisant POE et Tk et empaquetée pour la dissortingbution en utilisant pp. Elle utilise plusieurs fichiers externes; certains pour l’entrée dans le programme (données acquises du DNS) et d’autres pour les actions entresockets par l’utilisateur (création et suppression des enregistrements d’alias DNS).

Le packer PAR (pp) inclut des fichiers externes utilisant l’argument -a. Ces fichiers sont décompressés dans le répertoire \ inc sous un chemin “temp” créé par le package et disponible pour le script via

 $ENV{PAR_TEMP} 

La première étape de la solution consistait à append ces informations au POE “$ heap”. La ligne ci-dessous est dans l’état en ligne “_start”;

 $heap->{t_path} = "$ENV{PAR_TEMP}\\inc\\"; 

Comme je travaille dans l’environnement Win32, j’ai utilisé les barres obliques inversées pour append le répertoire \ inc au chemin temporaire.

Lors de l’appel d’un fichier externe pour l’entrée dans l’application, j’ai utilisé une variable (@zone) pour renvoyer les données;

 @zone = `$heap->{t_path}dnscmd aus-dc1 /enumrecords company.pvt @`; 

Pour que les appels aboutissent à des actions externes, les fichiers sont appelés sans enregistrer la sortie.

 `$heap->{t_path}cpau -dec -file $heap->{t_path}del_event.job -nowarn -wait`; 

Merci encore à tous pour votre consortingbution et merci à stackoverflow pour avoir fourni cet excellent environnement.

Voici quelque chose qui a fonctionné sur mon système:

 C: \ tmp> cat build.bat
 @Écho off
 sortie mkdir
 call pp -o runner.exe runner.pl -a sayhello.bat
 déplacer la sortie runner.exe \ runner.exe
  C: \ tmp> cat sayhello.bat
 @echo je dis bonjour ...

 C:\tmp> cat runner.pl #!/usr/bin/perl use ssortingct; 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__ 

Sortie:

 C:\tmp\output> runner.exe The output was: >>> I am saying hello ... <<< 

Cela semble un peu sale, cependant.