มีความแตกต่างที่แท้จริงระหว่างการเรียกใช้สคริปต์ด้วยหรือไม่
[sudo] sh ./<script>.run
แทน
[sudo] chmod +x ./<script>.run
[sudo] ./<script>.run
มีความแตกต่างที่แท้จริงระหว่างการเรียกใช้สคริปต์ด้วยหรือไม่
[sudo] sh ./<script>.run
แทน
[sudo] chmod +x ./<script>.run
[sudo] ./<script>.run
คำตอบ:
ถ้าคุณใช้
sh ./<script>.run
/bin/sh
(โดยปกติจะเป็นเชลล์เป้าหมาย) จะใช้เพื่อเรียกใช้สคริปต์ แน่นอนว่าจะใช้งานได้ก็ต่อเมื่อสคริปต์เขียนขึ้นสำหรับบอร์นเชลล์ บางครั้งเชลล์สคริปต์สำหรับ Linux ต้องการ Bash แทน Bourne shell ดังนั้นอาจไม่ทำงานแม้ว่าจะเป็นเชลล์สคริปต์
ถ้าคุณใช้
./<script>.run
เคอร์เนลดูที่บรรทัด shebangเพื่อค้นหาว่าโปรแกรมใดที่จะใช้เพื่อเรียกใช้โปรแกรม ดังนั้นวิธีนี้จึงใช้ได้แม้ว่าจะเป็น Bash, Perl, Python หรือสคริปต์อื่น ๆ
ดังนั้นนี่เป็นวิธีที่นิยมใช้ในการเรียกใช้สคริปต์
ตราบใดที่มันเป็นsh
เชลล์สคริปต์ (Dash หรือเทียบเท่า) ไม่มีความแตกต่างภายนอก
ปัญหา.run
ไม่ได้รับประกันว่าเป็นอย่างนั้น มันอาจเป็นเลขฐานสอง อาจเป็น Bash หรือ Python หรือ PHP หรืออะไรก็ได้ พวกเขาทั้งหมดมีเชลล์สคริปต์แฮช - ปัง หากคุณบังคับให้ทำsh
อย่างไม่รู้จบใครจะรู้ว่าจะเกิดอะไรขึ้น อาจเป็นข้อผิดพลาด แต่อาจเรียกใช้รหัสที่เป็นอันตรายก่อนที่จะถึงจุดนั้นได้
โดยการchmod
ding (เพื่อเปิดใช้งานบิตสิทธิ์การดำเนินการ) จากนั้นเรียกใช้./script.run
คุณจะให้โอกาสในการทำงานที่ดีที่สุดเท่าที่จะเป็นไปได้ ถ้ามันเป็นเชลล์สคริปต์แฮช - แบงของมันจะได้รับการวิเคราะห์อย่างถูกต้องและถ้ามันเป็นไบนารีที่ปฏิบัติการมันก็จะทำงานโดยกำเนิด
วิธีการทั้งสองวิธีสามารถกระทำเหมือนกัน แต่แตกต่างกัน
sh ./script
รันsh
คำสั่งด้วยอาร์กิวเมนต์./script
ซึ่งเกิดขึ้นกับรันสคริปต์ที่กำหนด .. แม้ว่าสคริปต์นั้นไม่ใช่sh
สคริปต์จริง(ไม่ดี)
./script
รันไฟล์ที่กำหนด ทำได้โดยค้นหาบรรทัด"shebang"เพื่อกำหนดว่าคำสั่งใดที่จะเรียกใช้ หากไม่ได้ระบุจะใช้sh
(ทั้งสองวิธีทำหน้าที่เหมือนกันในบางครั้ง) แต่บ่อยครั้งที่มีการระบุล่ามที่แตกต่างกัน ..
ตัวอย่างเช่นหากfilename
มีสิ่งต่อไปนี้:
#!/usr/bin/python
print "This is a Python script!"
.. จากนั้นคำสั่งทั้งสองแตกต่างกันมาก:
$ sh script
script: line 3: print: command not found
$ chmod +x script
$ ./script
This is a Python script!
หากไม่มีเส้น Shebang ทั้งสองจะเหมือนกัน:
$ cat script
echo "This is an sh script"
$ sh ./script
This is an sh script
$ ./script
This is an sh script
ความแตกต่างที่สำคัญอย่างหนึ่งคือหากบรรทัด hashbang ของคุณมีพารามิเตอร์ ตัวอย่างเช่นหากสคริปต์เริ่มต้นด้วย
#!/bin/bash -e
... และคุณเรียกใช้โดยใช้ภายนอกsh
หรือbash
บรรทัดนั้นจะถูกตีความว่าเป็นความคิดเห็นและถูกละเว้นดังนั้น-e
พารามิเตอร์ (ออกเมื่อล้มเหลว) จะไม่ถูกประมวลผล ดังนั้นให้สคริปต์ต่อไปนี้:
#!/bin/bash -e
echo Hello
false
echo goodbye
ผลลัพธ์สำหรับ./script
จะเป็นเพียง "Hello" แต่ผลลัพธ์สำหรับsh script
จะHello
ตามด้วยgoodbye
ซึ่งอาจไม่ได้มีเจตนา
นี่คือเหตุผลว่าทำไมคุณควรใช้set -e
คำสั่งแยกต่างหากเสมอ(มันเป็นความคิดที่ดีอยู่แล้ว - บ่อยกว่านั้นถ้ามีปัญหาในสคริปต์กลางคุณไม่ต้องการให้ถูกเพิกเฉย)
ไม่
[sudo] chmod +x ./<scrupt>.run
./<script>.run
ทำให้ปฏิบัติการสคริปต์เพื่อให้คุณสามารถเรียกใช้มันด้วย
ด้วย[sudo] sh ./<script>.run
คุณสามารถเรียกใช้แม้ว่ามันจะไม่สามารถใช้งานได้