เหตุใดฉันจึงไม่ได้รับข้อผิดพลาดทางไวยากรณ์เมื่อฉันรันสคริปต์ Python ด้วย Perl


85

ฉันเพิ่งเขียนโค้ดทดสอบ python ลงไปtest.pyและฉันจะเปิดใช้งานดังต่อไปนี้:

perl test.py

หลังจากนั้นไม่นานฉันก็ตระหนักถึงความผิดพลาดของฉัน ฉันพูดว่า "หลังจากนั้นสักครู่" เนื่องจากโค้ด Python ได้รับการดำเนินการอย่างถูกต้องจริง ๆ ราวกับว่าในล่าม Python!

เหตุใด Perl ของฉันจึงตีความ Python ของฉัน test.pyมีลักษณะดังนี้:

#!/usr/bin/python

...Python code here...

น่าสนใจถ้าฉันทำตรงกันข้าม (เช่นโทรpython something.pl) ฉันจะได้รับข้อผิดพลาดทางไวยากรณ์จำนวนมาก


6
ฉันเดาว่าเป็นเพราะ#!อยู่ในจุดเริ่มต้นของไฟล์ แน่นอนว่าถ้าฉันถอดเธอออกฉันจะได้รับพฤติกรรมที่คาดหวัง นั่นไม่ใช่ความคิดที่ไม่ดีจากมุมมองด้านความปลอดภัยใช่ไหม
Dacav

8
ไม่ใช่จุดของเส้นทาง Shebang เพื่อระบุล่าม หากคุณไม่ไว้วางใจให้โค้ดทำงานคุณก็ไม่ควรรันตั้งแต่แรก
Sobrique

1
ไม่ไม่จริงๆ สคริปต์ของคุณคือไฟล์ข้อความ ไม่มากไม่น้อย. มันจะไม่ 'วิ่ง' โดยไม่มีล่าม
Sobrique

4
"เหตุใด Perl ของฉันจึงตีความ Python ของฉัน" ไม่ใช่ "ปัญหาที่ไม่สามารถทำซ้ำได้อีกต่อไปหรือเป็นข้อผิดพลาดง่ายๆในการพิมพ์" โหวตให้เปิดอีกครั้ง การเพิ่มคะแนนของ Q และ A แสดงนี้เป็นคำถามที่ได้รับความนิยม
ikegami

1
@ikegami ไม่คำนึงถึงความนิยมอย่างชัดเจนนี่ไม่ใช่ "ข้อผิดพลาดในการพิมพ์ธรรมดา ๆ ... ได้รับการแก้ไขในลักษณะที่ไม่น่าจะช่วยผู้อ่านในอนาคตได้" โหวตให้เปิดอีกครั้ง
ThisSuitIsBlackNot

คำตอบ:


114

จากperlrun ,

หาก#!บรรทัดไม่มีคำว่า "perl" หรือคำว่า "indir" โปรแกรมที่ตั้งชื่อตามโปรแกรม#!จะถูกเรียกใช้งานแทนตัวแปลภาษา Perl นี่เป็นเรื่องแปลกเล็กน้อย แต่ช่วยให้ผู้ที่ใช้งานเครื่องไม่ได้ทำ#!เพราะสามารถบอกโปรแกรมได้ว่า SHELL คือ/ usr / bin / perlจากนั้น Perl จะส่งโปรแกรมไปยังล่ามที่ถูกต้องสำหรับพวกเขา

ตัวอย่างเช่น,

$ cat a
#!/bin/cat
meow

$ perl a
#!/bin/cat
meow

32
ว้าว. พูดคุยเกี่ยวกับคุณสมบัติที่คลุมเครือของคุณ ฉันใช้ Perl มานานกว่า 20 ปีแล้วและฉันไม่รู้ว่ามันทำอย่างนั้น
cjm

4
ฉันเริ่มใช้ Perl v4 บน DOS, VMS และ Solaris เป็นคุณสมบัติที่ไม่เชื่อเรื่องพระเจ้า / เชื่อมโยงระบบปฏิบัติการเช่นนี้ที่ทำให้ชีวิตข้ามแพลตฟอร์มง่ายขึ้นมาก
tjd

1
@MarcvanLeeuwen เมื่อคุณเขียนโปรแกรมสำหรับ Linux, OSX, VAX / VMS, Windows, Solaris, OS / 2 และสิ่งอื่น ๆ ที่น่ารำคาญที่สุดของการพอร์ตโปรแกรมภาษาสคริปต์คือการเริ่มต้นระบบเหล่านี้แม้ว่าโดยปกติแล้ว การแบ่งปันคุณลักษณะ "พิมพ์คำสั่งพบและดำเนินการ" เหมือนกันทำเกือบทุกอย่างแตกต่างกัน คุณลักษณะนี้จะทำให้ Perl Perl ง่ายช่องว่างสะพานในการทำงาน - คุณสามารถเขียนเพียง shebang Unix สไตล์และถ้า Perl เป็นปัจจุบันรหัสไม่ว่าจะเป็นรหัส Perl หรือไม่จะเสมองาน - #! /usr/bin/env fooมันเหมือนสากลมากขึ้น
zxq9

1
@immibis จากเธรดShebang line ที่แยกวิเคราะห์ความลึกลับในรายชื่อส่งเมลของ perl5-porters: " indirเป็นโปรแกรมที่ออกแบบมาเพื่อเรียกใช้งานโปรแกรมอื่น ๆ ทางอ้อมความทรงจำของฉันคือมันควรจะมีประโยชน์อย่างยิ่งในสถานการณ์ setuid ที่ระบบปฏิบัติการไม่ได้ให้มาโดยกำเนิด คุณช่วยได้มากและ / หรือบางทีในสถานการณ์ที่เคอร์เนลระบบปฏิบัติการ จำกัด คุณไว้ที่บรรทัดคำสั่ง 32 อักขระ "
ThisSuitIsBlackNot

2
นี่เป็นเพียงการตอกย้ำชื่อเสียงของ Perl ในฐานะอ่างล้างจานของภาษาโปรแกรม จากการสังเกตที่น่าสนใจฉันเชื่อว่าการใช้งานดั้งเดิมของ shebang นั้นเป็นเพียงคุณลักษณะของเชลล์ซึ่งจะย้ายไปยังเคอร์เนล Unix ในภายหลังเท่านั้น Perl มีกลไกเชลล์จำนวนมาก (เช่น backticks สำหรับการแทนที่เอาต์พุตคำสั่ง) นี่เป็นเพียงอีกหนึ่ง
Barmar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.