Sự khác biệt giữa việc gọi một tập lệnh perl thông qua sh hoặc perl


7

Tôi có một kịch bản Hello World perl đơn giản.

#!/usr/bin/perl

print 'Hello world.';

Nó hoạt động tốt nếu tôi chạy qua perl <file_name>, nhưng không thành công tôi chạy qua sh <file_name>.

Sự hiểu biết của tôi về dòng đầu tiên là nó gọi shell perl (tương tự #! / Usr / bin / bash sẽ gọi shell bash). Vì vậy, sự khác biệt giữa hai lệnh là gì?

Tôi tìm thấy chủ đề này http://ubuntuforums.org/showthread.php?t=1133334 nói rằng sh <file_name> "Trong trường hợp đó, bạn không chạy Perl chút nào, nhưng trình bao, sẽ gọi chương trình là 'in'." NẾU đó là trường hợp #! chỉ được giải thích như một bình luận. Nếu vậy, nó có cần thiết không?

(Tôi biết rằng tôi có thể chmod + x tệp và chạy nó một cách trực tiếp, nhưng tôi chỉ muốn biết sự khác biệt giữa hai phương thức tôi đang sử dụng)

Câu trả lời:


6

Nếu bạn thực hiện một tập tin trực tiếp

/path/to/script/filename

Dòng shebang sẽ được tìm kiếm cho trình thông dịch để chạy nó. Nếu bạn chạy perlhoặc shvới một đối số, chúng sẽ hoạt động như tài liệu: cố gắng diễn giải tệp dưới dạng tập lệnh trong Perl hoặc shell, tương ứng.

Khi bạn đặt rõ ràng trình thông dịch từ dòng lệnh (chẳng hạn như sh foo.plhoặc perl foo.pl), dòng shebang không được sử dụng để xác định trình thông dịch sẽ chạy. Nó được phân tích cú pháp cho các tùy chọn có thể, (ví dụ với một #!/usr/bin/perl -wshebang, chạy tập lệnh như perl foo.plsẽ bật -wcờ) nhưng nó không được sử dụng để xác định chương trình nào sẽ diễn giải tập lệnh.

Vì vậy, chạy tập lệnh perl như sh foo.plcó nghĩa là hệ thống của bạn sẽ cố gắng diễn giải nó thành shtập lệnh thay vào đó, mặc dù dòng perl shebang.


@terdon: Không hoàn toàn chính xác với bản cập nhật của bạn. perl sẽ phân tích dòng shebang trong một tập lệnh cho các thiết bị chuyển mạch.
Dubu

@Dubu ngay cả khi tập lệnh đó được khởi chạy là sh foo.pl? Perl thậm chí sẽ không được gọi trong trường hợp đó, nó sẽ phân tích shebang như thế nào? Các công việc được chỉ đọc nếu bạn không chỉ định một thông dịch viên ( shhoặc perlhoặc bất cứ điều gì) khi tung ra kịch bản. Đó là vấn đề mà OP đang phải đối mặt. Nó thực sự sẽ được phân tích cú pháp nếu bạn khởi chạy với trình thông dịch chính xác ( perl foo.pl) nhưng không phải nếu bạn sử dụng sai ( sh foo.pl).
terdon

@terdon: Câu trả lời bây giờ nói rằng dòng shebang sẽ bị bỏ qua khi tập lệnh được gọi là đối số perl hoặc sh . Tôi muốn chỉ ra rằng điều này không giữ khi được gọi là perl <filename>.
Dubu

@Dubu đủ công bằng. Rõ ràng hơn bây giờ?
terdon

@terdon Gần như hoàn hảo. Tất nhiên, dòng shebang có được giải thích hay không phụ thuộc vào người phiên dịch. perlphải không, vì shtôi không biết.
Dubu

1

Vì vậy, bạn đã không làm cho kịch bản thực thi? Bạn sẽ không tự động cho rằng mọi thứ với các phần mở rộng tệp đó là có thể thực thi được, vì vậy bạn cần phải chạy perl <file name>hoặc bạn cần làm cho nó có thể thực thi được vớichmod +x


0

Cả hai có thể không giống nhau tùy thuộc vào cách Perl được cài đặt trên hệ thống bạn đang sử dụng. Hãy thử nhập lệnh này:

which perl

Nó sẽ chỉ cho bạn đường dẫn đến tệp thực thi có tên là "perl" trong $PATH(loại echo $PATHđể xem của bạn $PATH). Trên nhiều hệ thống, đây sẽ /usr/bin/perllà nơi Perl thường được cài đặt - đây là lý do tại sao dòng "shebang" khi bắt đầu hầu hết các tập lệnh Perl cũng cho rằng nó ở đó.

Tuy nhiên, trên một số hệ thống, đường dẫn đến perlcó thể khác nhau. Trong trường hợp đó, bạn có thể nhận được một kết quả gõ khác perl your_script.plso với sử dụng shell để diễn giải dòng shebang, ví dụ ./your_script.pl; trong trường hợp trước, perlthông dịch viên trong ý chí của bạn $PATHsẽ diễn giải kịch bản của bạn, trong trường hợp sau, người phiên dịch theo /usr/bin/perlý muốn. Đây có thể không giống nhau.

Trong nhiều trường hợp, perllà cài đặt Perl của riêng bạn, có thể mới hơn so với cài đặt đi kèm với hệ thống (trong /usr/bin). Nói cách khác, có nhiều hơn một trình thông dịch Perl trên hệ thống. Trong trường hợp đó, bạn nên tìm ra cái nào bạn muốn và mã hóa đường dẫn của nó trong dòng shebang của bạn để tập lệnh của bạn không bị hiểu nhầm với phiên bản sai của Perl. (Bạn cũng có thể viết những thứ như use 5.12;trong tập lệnh của mình để đảm bảo an toàn hơn về vấn đề này.) Để kiểm tra phiên bản của trình thông dịch Perl, hãy nhập /path/to/perl -v.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.