2009-07-14 35 views
6

C'est ma tentative de couper à travers les questions étrangères soulevées "Why don’t my system calls work in the Perl program I wrap with pp?" J'ai créé un script simple Perl sur un système linux:Où pp (PAR) déballe-t-il les fichiers d'ajout (-a)?

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 simple fichier shell:

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

je p pour emballer le script Perl avec le script shell dans 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 

Si je cours le fichier compressé dans un autre répertoire mpty, le script shell ne se trouve pas:

 
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 

Si je copie le script shell dans le répertoire, le script emballé fonctionne comme prévu:

 
new-net:~/test # ./ls_test
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

Alors, où un attendre scénario emballé pp trouver un fichier inclus? Et comment un appel à ce fichier inclus doit-il être configuré dans le script Perl d'origine?

Répondre

6

Les fichiers d'un fichier exécutable empaqueté sont extraits dans un répertoire temporaire (généralement/tmp/par-USERNAME/cache-XXXXXXX). Pour accéder à ces fichiers font quelque chose comme ce qui 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 symolic à l'exécutable qui ont le même nom que le script que vous voulez exécuter, et exécuter ceux-ci.

En fait, relisant votre question, l'accès à 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; 
+1

à partir de perldoc PAR; run Le nom d'un script à exécuter dans le par. Les sorties sont terminées. Est-ce que cela signifie que tout appel à un fichier ajouté quitte le script empaqueté? Le problème que j'essayais à l'origine de résoudre est un script POE/TK qui appelle divers fichiers externes à partir des commandes du widget. – jpolache

3

Voici quelque chose qui fonctionne sur mon système:

 
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__ 

Sortie:

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

Cela semble un peu sale, cependant.

+0

On dirait que sur MSWindows le répertoire cache/temp par défaut pour PAR est le répertoire courant. – Inshallah

+2

Nope, C: \ DOCUME ~ 1 \ nom d'utilisateur \ LOCALS ~ 1 \ Temp \ par-nom d'utilisateur \ cache-07b6bc6c42c824d8fdd5abd08eb8b67b2bf7ecab ... Cependant, votre commentaire m'a fait réaliser que j'avais oublié de réparer le 'build.bat' dans le post . –

+1

L'utilisation de PAR_TEMP est-elle sale? Je n'ai trouvé aucun autre moyen de se référer au répertoire d'extraction. Vous pouvez bien sûr extraire vous-même les archives, alors vous savez où c'est. – Inshallah

4

Merci à tous pour votre contribution à cette réponse. J'ajoute cette réponse pour distiller les parties de la contribution inestimable de chacun que j'ai utilisé pour trouver la solution qui a fonctionné pour moi dans mon application particulière.

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

L'emballeur 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éée par l'emballage et à la disposition du script via

$ENV{PAR_TEMP}

La première étape dans la solution était d'ajouter cette information au POE « tas $ » . 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 antislashs échappées pour ajouter le répertoire \ inc dans le chemin temporaire.

Lors de l'appel d'un fichier externe pour la saisie dans l'application, j'ai utilisé une variable (@zone) pour retourner les données;

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

Pour les appels visant à effectuer 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 contribution et grâce à stackoverflow pour avoir fourni cet environnement génial.

+3

utilisez 'File :: Spec-> catfile ($ ENV {PAR_TEMP}, 'inc')' plutôt que de jouer avec des antislash doubles. Au fait, je suis un peu surpris que je sois le seul à avoir mis en doute les réponses dans ce fil de discussion: La façon dont vous montrez votre appréciation sur le SO c'est d'upvoter les réponses. –