2009-07-14 16 views
6

To moja próba przeciąć obcych kwestii poruszonych "Why don’t my system calls work in the Perl program I wrap with pp?" stworzyłem prosty skrypt Perl w systemie Linux:Skąd pp (PAR) rozpakowuje pliki dodawania (-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"; 

Ten skrypt wywołuje prosty plik shell:

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

użyłem pp aby spakować skrypt Perla wraz ze skryptem powłoki do 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 

Jeśli uruchomię spakowany plik w Katalog mpty skrypt powłoki nie zostanie znaleziony:

 
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 

Gdybym skopiuj skrypt do katalogu, zapakowany skrypt działa zgodnie z oczekiwaniami:

 
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

Więc, gdzie robi pp pakowane skrypt spodziewać znaleźć dołączony plik? W jaki sposób należy skonfigurować wywołanie tego pliku w oryginalnym skrypcie Perla?

Odpowiedz

6

Pliki w pliku spakowanym są wyodrębniane do katalogu tymczasowego (zwykle/tmp/par-NAZWA_UŻYTKOWNIKA/pamięć podręczna-XXXXXXX). Aby uzyskać dostęp do tych plików zrobić coś jak następuje:

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

Można również dokonać symolic łącza do pliku wykonywalnego, które mają taką samą nazwę jak skrypt, który chcesz uruchomić i uruchomić te.

Właściwie rereading swoje pytanie, po prostu z dostępem do zmiennej środowiskowej PAR_TEMP jest prawdopodobnie bardziej przydatne:

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

od perldoc PAR; run Nazwa skryptu do uruchomienia w par. Po zakończeniu kończy pracę. Czy to oznacza, że ​​każde wywołanie dodanego pliku wychodzi z pakowanego skryptu? Problem, który początkowo próbowałem rozwiązać, to skrypt POE/TK, który wywołuje różne pliki zewnętrzne z poleceń widgetów. – jpolache

3

Oto coś, co działało na moim systemie:

 
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__ 

Wyjście:

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

Czuje się jednak trochę brudno.

+0

Wygląda na MSWindows domyślny katalog cache/temp dla PAR jest bieżącym katalogiem. – Inshallah

+2

Nie, C: \ DOCUME ~ 1 \ nazwa_użytkownika \ LOKALNE ~ 1 \ Temp \ par-username \ cache-07b6bc6c42c824d8fdd5abd08eb8b67b2bf7ecab ... Jednak twój komentarz uświadomił mi, że zapomniałem naprawić 'build.bat' w poście . –

+1

Używanie PAR_TEMP jest brudne? Nie znalazłem żadnych innych sposobów odwołania się do katalogu ekstrakcji. Możesz oczywiście wyodrębnić archiwum samodzielnie, wtedy wiesz, gdzie to jest. – Inshallah

4

Dziękuję wszystkim za wniesienie wkładu w tę odpowiedź. Dodaję tę odpowiedź, aby wydestylować części nieocenionego wkładu wszystkich, z których korzystałem, aby znaleźć rozwiązanie, które zadziałało w moim konkretnym zgłoszeniu.

Aplikacja jest napisana w Perl ActiveState za pomocą POE i Tk i pakowana do dystrybucji za pomocą pp. Korzysta z wielu plików zewnętrznych; niektóre do wprowadzania do programu (zmanipulowane dane z DNS), a niektóre do działań podejmowanych przez użytkownika (tworzenie i usuwanie rekordów aliasów DNS).

Pakowaczka PAR (pp) zawiera pliki zewnętrzne za pomocą argumentu -a.Te pliki są rozpakowywane do katalogu \ inc pod „Temp” ścieżki utworzonej przez pakiet i dostępny do skryptu przez

$ENV{PAR_TEMP}

Pierwszym krokiem w roztworze było dodać te informacje do POE „$ sterty” . Linia poniżej znajduje się w stanie "_start" w linii;

Podczas pracy w środowisku Win32 użyłem uciekinierskich ukośników odwrotnych do dołączenia katalogu \ inc do ścieżki tymczasowej.

Podczas wywoływania pliku zewnętrznego do wprowadzania do aplikacji, użyłem zmiennej (@zone), aby zwrócić dane;

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

W przypadku wywołań w celu wykonania działań zewnętrznych pliki są wywoływane bez zapisywania danych wyjściowych;

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

Jeszcze raz dziękuję wszystkim za przyczynianie się i dzięki stackoverflow za zapewnienie tego wspaniałego środowiska.

+3

użyj 'Plik :: Spec-> catfile ($ ENV {PAR_TEMP}, 'inc')' zamiast mieszać z podwójnymi ukośnikami odwrotnymi. Przy okazji, jestem trochę zaskoczony, że jestem jedynym, który wznowił jakiekolwiek odpowiedzi w tym wątku: sposób, w jaki okazujesz uznanie dla SO, polega na przegłosowaniu odpowiedzi. –