2016-03-21 22 views
14

Khi tôi thực hiện system() cuộc gọi trong Perl, tôi thường kiểm tra mã trả lại theo số perldocs. Vâng, tôi nghĩ vậy. Phần lớn thời gian $rc!=0 là đủ cho tôi. Gần đây tôi đã giúp hai người ở đây gặp sự cố với các cuộc gọi system() khi chạy tập lệnh .cgi của họ dưới apache. Tôi hướng dẫn họ để kiểm tra $rc của

my $rc = system(...); 

và liên kết chúng với system() tài liệu. Sau đó, tôi nhìn kỹ hơn và nhận thấy các tài liệu không thực sự nói về $rc nhưng thay vì về $? và tôi cảm thấy một chút xấu hổ và những câu dưới đây nảy sinh:

Có một sự khác biệt giữa:

system(...); 
if ($? == -1) { 
    print "failed to execute: $!\n"; 
} 
elsif ($? & 127) { 
    printf "child died with signal %d, %s coredump\n", 
     ($? & 127), ($? & 128) ? 'with' : 'without'; 
} 
else { 
    printf "child exited with value %d\n", $? >> 8; 
} 

my $rc = system(...); 
if ($rc == -1) { 
    print "failed to execute: $!\n"; 
} 
elsif ($rc & 127) { 
    printf "child died with signal %d, %s coredump\n", 
     ($rc & 127), ($rc & 128) ? 'with' : 'without'; 
} 
else { 
    printf "child exited with value %d\n", $rc >> 8; 
} 

Hoặc, đối với ngắn hạn, là $rc bằng $? cho system()?

Tôi đã xem qua các tài liệu của system, wait$? nhưng không rõ ràng đối với tôi. Tôi đã làm sai trong 15 năm qua bằng cách sử dụng $rc?

+1

Nếu bạn chụp kết quả cho '$ rc' không có cơ hội của' $ 'thay đổi trên bạn trước khi bạn nhận được xung quanh để? bằng cách sử dụng giá trị đó. – tadman

+0

Cảm ơn @tadman. Tôi đã thêm nhận xét vào câu trả lời được chấp nhận cũng áp dụng cho nhận xét của bạn. Sử dụng '$ rc' có vẻ là cách sạch hơn với tôi. – PerlDuck

Trả lời

10

Có, giá trị trả lại của systemnên bằng $?.

Tuy nhiên kể từ khi $? không chỉ áp dụng cho các cuộc gọi và system$? là một biến toàn cầu, nó có thể được ghi đè bởi các hành động khác đang xảy ra. Từ perldoc -v '$?' này bao gồm:

$ CHILD_ERROR

$?

Trạng thái được trả về bởi lệnh đóng cuối cùng, backtick ("` `"), gọi thành công là "wait()" hoặc "waitpid()" hoặc từ toán tử "system()".

Nó là xa an toàn để lưu trữ các giá trị ngay lập tức sau đó so sánh:

my $rc = system('ls myfile.txt'); 
if ($rc >> 8 != 0) { 
    # do something because ls exited with an error 
} 
+0

Tuyệt vời! Đó là những gì tôi muốn nghe và chắc chắn. Cảm ơn bạn. Tôi biết về sự biến động của '$?' (Như errno trong C) và chỉ sử dụng nó nếu không có sẵn $ rc (giống như với backticks). Tôi thích vars rõ ràng anyway và thậm chí tránh '$ _' khi có thể. Khả năng đọc và bảo trì IMHO bị sử dụng quá nhiều _magic_ vars. Vì vậy, tôi sẽ gắn bó với '$ rc'. :-) – PerlDuck

+2

'$?' Là khá giống hệt như của 'đáng kính' C có nghĩa là nó có rất nhiều vấn đề tương tự. Biến toàn cầu huyền diệu chắc chắn có vẻ như một ý tưởng tuyệt vời một lần, nhưng may mắn thay, chúng tôi đã chuyển sang. – tadman

+3

@tadman Trên thực tế, '$!' Khá giống hệt 'errno' (nó đơn giản truy lục giá trị hiện tại của' errno'). '$?'hơi khác một chút bởi vì nó được thiết lập bởi mỗi' wait' hoặc pipe close, ngay cả khi chúng thành công ('$!' chỉ hợp lệ ngay sau khi thất bại). Nhưng bạn nói đúng về các biến toàn cục. – ThisSuitIsBlackNot

Các vấn đề liên quan