2009-07-14 21 views
6

Đây là nỗ lực của tôi để cắt giảm thông qua các vấn đề không liên quan huy động "Why don’t my system calls work in the Perl program I wrap with pp?" Tôi đã tạo ra một kịch bản Perl đơn giản trên một hệ thống Linux:Trang (PAR) giải nén tập tin (-a) ở đâu?

new-net:~/scripts # cat ls_test.pl 
@ls_out = `ls -l`; 

map { print "$_\n" } @ls_out; 

$out = `sh out_test.sh`; 

print "$out\n"; 

kịch bản này đòi hỏi một file shell đơn giản:

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

tôi đã sử dụng pp để đóng gói tập lệnh Perl cùng với tập lệnh shell vào 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 

Nếu tôi chạy tệp được đóng gói theo cách khác mpty thư mục, các tập lệnh shell không được tìm thấy:

 
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 

Nếu tôi sao chép các tập lệnh shell vào thư mục, kịch bản đóng gói chạy như mong đợi:

 
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

Vì vậy, nơi nào một kịch bản đóng gói pp mong đợi để tìm một tệp được bao gồm? Và làm thế nào một cuộc gọi đến tập tin được bao gồm được cấu hình trong kịch bản Perl gốc?

Trả lời

6

Các tệp trong tệp thi hành được đóng gói được trích xuất vào thư mục tạm thời (thường là/tmp/par-USERNAME/cache-XXXXXXX). Để truy cập vào những tập tin này làm một cái gì đó như sau:

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

Bạn cũng có thể tạo liên kết symolic để thực thi có tên giống như kịch bản mà bạn muốn chạy, và chạy các.

Trên thực tế, đọc lại câu hỏi của bạn, bạn chỉ cần truy cập vào biến môi trường PAR_TEMP có lẽ hữu ích hơn:

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

từ cải cách hành chính perldoc; run Tên của tập lệnh chạy theo mệnh giá. Thoát khi hoàn tất. Điều này có nghĩa là mọi cuộc gọi đến tệp được thêm sẽ thoát khỏi tập lệnh được đóng gói? Vấn đề ban đầu tôi đang cố gắng giải quyết là một kịch bản POE/TK gọi các tệp bên ngoài khác nhau từ các lệnh widget. – jpolache

3

Dưới đây là một cái gì đó mà làm việc trên hệ thống của tôi:

 
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__ 

Đầu ra:

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

Điều này có vẻ hơi bẩn.

+0

Hình như trên MSWindows thư mục cache/temp mặc định cho PAR là thư mục hiện hành. – Inshallah

+2

Không, C: \ DOCUME ~ 1 \ tên người dùng \ LOCALS ~ 1 \ Temp \ par-username \ cache-07b6bc6c42c824d8fdd5abd08eb8b67b2bf7ecab ... Tuy nhiên, nhận xét của bạn khiến tôi nhận ra rằng tôi đã quên sửa 'build.bat' trong bài đăng . –

+1

Sử dụng PAR_TEMP có bị bẩn không? Tôi đã không tìm thấy bất kỳ phương tiện khác để tham khảo thư mục khai thác. Tất nhiên bạn có thể tự giải nén kho lưu trữ, sau đó bạn biết nó ở đâu. – Inshallah

4

Cảm ơn mọi người đã đóng góp cho câu trả lời này. Tôi đang thêm câu trả lời này để chưng cất các phần đầu vào vô giá của mọi người mà tôi đã sử dụng để đưa ra giải pháp làm việc cho tôi trong ứng dụng cụ thể của tôi.

Ứng dụng được viết bằng ActiveState Perl sử dụng POE và Tk và được đóng gói để phân phối bằng pp. Nó sử dụng một số tệp bên ngoài; một số cho đầu vào vào chương trình (dữ liệu được nén từ DNS) và một số cho các hành động được thực hiện bởi người dùng (tạo và xóa các bản ghi bí danh DNS).

Trình đóng gói cải cách hành chính (trang) bao gồm các tệp bên ngoài bằng cách sử dụng đối số -a.Những tập tin được giải nén vào thư mục \ inc dưới một "tạm thời" con đường tạo ra bởi các gói và sẵn sàng cho kịch bản qua

$ENV{PAR_TEMP}

Bước đầu tiên trong các giải pháp là để thêm thông tin này để POE "$ đống" . Dòng bên dưới nằm trong trạng thái nội dòng "_start";

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

Vì tôi đang làm việc trong môi trường Win32, tôi đã sử dụng dấu gạch chéo thoát để nối thư mục \ inc vào đường dẫn tạm thời.

Khi gọi tệp bên ngoài để nhập vào ứng dụng, tôi đã sử dụng biến (@zone) để trả lại dữ liệu;

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

Đối với các cuộc gọi để hoàn tất tác vụ bên ngoài, tệp được gọi mà không lưu đầu ra;

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

Xin cảm ơn tất cả mọi người đã đóng góp và nhờ lưu lượng truy cập để cung cấp môi trường tuyệt vời này.

+3

sử dụng 'Tệp :: Spec-> catfile ($ ENV {PAR_TEMP},' inc ') 'thay vì gây rối với các dấu gạch chéo ngược đôi. Nhân tiện, tôi ngạc nhiên một chút rằng tôi là người duy nhất đã upvoted bất kỳ câu trả lời trong chủ đề này: Cách bạn thể hiện sự đánh giá cao về SO là bằng cách trả lời upvoting. –