Ai đó có thể vui lòng giúp tôi? Trong Perl, sự khác biệt giữa:
exec "command";
và
system("command");
và
print `command`;
Có những cách khác để chạy lệnh shell?
Ai đó có thể vui lòng giúp tôi? Trong Perl, sự khác biệt giữa:
exec "command";
và
system("command");
và
print `command`;
Có những cách khác để chạy lệnh shell?
Câu trả lời:
thực hiện một lệnh và không bao giờ trở lại . Nó giống như một return
tuyên bố trong một chức năng.
Nếu lệnh không được tìm thấy exec
trả về false. Nó không bao giờ trả về true, bởi vì nếu lệnh được tìm thấy thì nó không bao giờ trả về cả. Ngoài ra còn có không có điểm trong trở lại STDOUT
, STDERR
hoặc trạng thái thoát của lệnh. Bạn có thể tìm tài liệu về nó trong perlfunc
, bởi vì nó là một chức năng.
thực thi một lệnh và tập lệnh Perl của bạn được tiếp tục sau khi lệnh kết thúc.
Giá trị trả về là trạng thái thoát của lệnh. Bạn có thể tìm tài liệu về nó trong perlfunc
.
như system
thực thi một lệnh và tập lệnh perl của bạn được tiếp tục sau khi lệnh kết thúc.
Ngược lại với system
giá trị trả về là STDOUT
của lệnh.
qx//
tương đương với backticks. Bạn có thể tìm tài liệu về nó trong perlop
, bởi vì không giống như system
và exec
nó là một toán tử.
Những gì còn thiếu ở trên là một cách để thực thi lệnh không đồng bộ. Điều đó có nghĩa là tập lệnh perl của bạn và lệnh của bạn chạy đồng thời. Điều này có thể được thực hiện với open
. Nó cho phép bạn đọc STDOUT
/ STDERR
và ghi vào STDIN
lệnh của bạn. Nó phụ thuộc vào nền tảng.
Ngoài ra còn có một số mô-đun có thể dễ dàng thực hiện nhiệm vụ này. Có IPC::Open2
và IPC::Open3
và IPC::Run
, cũng như
Win32::Process::Create
nếu bạn đang ở trên cửa sổ.
Trong tôi sử dụng chung system
, open
, IPC::Open2
, hoặc IPC::Open3
tùy thuộc vào những gì tôi muốn làm. Các qx//
nhà điều hành, trong khi đơn giản, là quá hạn chế về tính năng của nó sẽ được bên ngoài rất hữu ích của hacks nhanh chóng. Tôi tìm open
đến nhiều hơn.
system
: chạy một lệnh và đợi cho nó trở lạiSử dụng system
khi bạn muốn chạy một lệnh, không quan tâm đến đầu ra của nó và không muốn tập lệnh Perl làm bất cứ điều gì cho đến khi lệnh kết thúc.
#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");
hoặc là
#spawns a shell, arguments are interpreted by the shell, use only if you
#want the shell to do globbing (e.g. *.txt) for you or you want to redirect
#output
system("command arg1 arg2 arg3");
qx//
hoặc `` : chạy một lệnh và bắt STDOUT của nóSử dụng qx//
khi bạn muốn chạy một lệnh, ghi lại những gì nó ghi vào STDOUT và không muốn tập lệnh Perl làm bất cứ điều gì cho đến khi lệnh kết thúc.
#arguments are always processed by the shell
#in list context it returns the output as a list of lines
my @lines = qx/command arg1 arg2 arg3/;
#in scalar context it returns the output as one string
my $output = qx/command arg1 arg2 arg3/;
exec
: thay thế quy trình hiện tại bằng quy trình khác.Sử dụng exec
cùng với fork
khi bạn muốn chạy một lệnh, không quan tâm đến đầu ra của nó và không muốn đợi nó trở lại. system
thực sự chỉ là
sub my_system {
die "could not fork\n" unless defined(my $pid = fork);
return waitpid $pid, 0 if $pid; #parent waits for child
exec @_; #replace child with new process
}
Bạn cũng có thể muốn đọc waitpid
và perlipc
hướng dẫn sử dụng.
open
: chạy một quy trình và tạo một đường ống đến STDIN hoặc STDERR của nóSử dụng open
khi bạn muốn ghi dữ liệu vào STDIN của quy trình hoặc đọc dữ liệu từ STDOUT của quy trình (nhưng không phải cả hai cùng một lúc).
#read from a gzip file as if it were a normal file
open my $read_fh, "-|", "gzip", "-d", $filename
or die "could not open $filename: $!";
#write to a gzip compressed file as if were a normal file
open my $write_fh, "|-", "gzip", $filename
or die "could not open $filename: $!";
Sử dụng IPC::Open2
khi bạn cần đọc và ghi vào STDIN và STDOUT của một tiến trình.
use IPC::Open2;
open2 my $out, my $in, "/usr/bin/bc"
or die "could not run bc";
print $in "5+6\n";
my $answer = <$out>;
sử dụng IPC::Open3
khi bạn cần nắm bắt cả ba xử lý tệp tiêu chuẩn của quy trình. Tôi sẽ viết một ví dụ, nhưng nó hoạt động chủ yếu giống như cách IPC :: Open2 thực hiện, nhưng với một thứ tự hơi khác với các đối số và xử lý tệp thứ ba.
Hàm exec thực thi một lệnh hệ thống và không bao giờ trả về - sử dụng hệ thống thay vì exec nếu bạn muốn nó trả về
Thực hiện chính xác điều tương tự như DANH SÁCH điều hành, ngoại trừ việc một ngã ba được thực hiện trước và quy trình cha mẹ chờ quá trình con hoàn thành.
Ngược lại với exec và system , backticks không cung cấp cho bạn giá trị trả về mà là STDOUT được thu thập.
Một chuỗi (có thể) được nội suy và sau đó được thực thi như một lệnh hệ thống với / bin / sh hoặc tương đương. Shell ký tự, đường ống và chuyển hướng sẽ được vinh danh. Đầu ra tiêu chuẩn được thu thập của lệnh được trả về ; lỗi tiêu chuẩn không bị ảnh hưởng.
Trong các trường hợp phức tạp hơn, nơi bạn muốn tìm nạp STDOUT, STDERR hoặc mã trả về, bạn có thể sử dụng các mô-đun tiêu chuẩn nổi tiếng như IPC :: Open2 và IPC :: Open3 .
Thí dụ:
use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
Cuối cùng, IPC :: Chạy từ CPAN cũng đáng để xem
Sự khác biệt giữa backticks của Perl ( `
) system
và là exec
gì?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
exec
exec
thực thi một lệnh và không bao giờ nối lại tập lệnh Perl. Đó là một kịch bản như một return
tuyên bố là một chức năng.
Nếu lệnh không được tìm thấy, exec
trả về false. Nó không bao giờ trả về true, bởi vì nếu lệnh được tìm thấy, nó sẽ không bao giờ trả về. Ngoài ra còn có không có điểm trong trở lại STDOUT
, STDERR
hoặc trạng thái thoát của lệnh. Bạn có thể tìm tài liệu về nó trong perlfunc , bởi vì nó là một hàm.
Ví dụ:
#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";
Trong đoạn mã trên, có ba print
câu lệnh, nhưng do để exec
lại tập lệnh, chỉ có câu lệnh in đầu tiên được thực thi. Ngoài ra, exec
đầu ra lệnh không được gán cho bất kỳ biến nào.
Ở đây, chỉ bạn mới nhận được đầu ra của print
câu lệnh đầu tiên và thực hiện ls
lệnh trên tiêu chuẩn.
system
system
thực thi một lệnh và tập lệnh Perl của bạn được nối lại sau khi lệnh kết thúc. Giá trị trả về là trạng thái thoát của lệnh. Bạn có thể tìm tài liệu về nó trong perlfunc .
Ví dụ:
#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";
Trong mã trên, có ba print
tuyên bố. Khi tập lệnh được nối lại sau system
lệnh, cả ba câu lệnh in được thực thi.
Ngoài ra, kết quả của việc chạy system
được gán cho data2
, nhưng giá trị được gán là 0
(mã thoát từ ls
).
Ở đây, bạn nhận được đầu ra của print
câu lệnh đầu tiên , sau đó là câu ls
lệnh, tiếp theo là đầu ra của hai print
câu lệnh cuối cùng trên tiêu chuẩn.
`
)Giống như system
, việc bao quanh một lệnh trong backticks thực thi lệnh đó và tập lệnh Perl của bạn được nối lại sau khi lệnh kết thúc. Ngược lại system
, giá trị trả về là STDOUT
của lệnh. qx//
tương đương với backticks. Bạn có thể tìm tài liệu về nó trong perlop , vì không giống như hệ thống và exec
, nó là một toán tử.
Ví dụ:
#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
Trong đoạn mã trên, có ba print
câu lệnh và cả ba câu lệnh đang được thực thi. Đầu ra của ls
sẽ không được tiêu chuẩn hóa trực tiếp, nhưng được gán cho biến data2
và sau đó được in bằng câu lệnh in cuối cùng.
Sự khác biệt giữa 'exec' và 'system' là exec thực hiện thay thế chương trình hiện tại của bạn bằng 'lệnh' và KHÔNG BAO GIỜ quay trở lại chương trình của bạn. mặt khác, hệ thống sẽ rẽ nhánh và chạy 'lệnh' và trả về cho bạn trạng thái thoát của 'lệnh' khi chạy xong. Dấu kiểm phía sau chạy 'lệnh' và sau đó trả về một chuỗi biểu thị tiêu chuẩn của nó (bất cứ điều gì nó sẽ được in ra màn hình)
Bạn cũng có thể sử dụng popen để chạy các lệnh shell và tôi nghĩ rằng có một mô-đun shell - 'use shell' cho phép bạn truy cập rõ ràng vào các lệnh shell điển hình.
Hy vọng rằng làm rõ nó cho bạn.
use Shell;
( search.cpan.org/dist/Shell/Shell.pm )? Nó không được cài đặt rộng rãi, cũng không phải là áp dụng đối với các câu hỏi, tôi nghĩ ...