การรันสคริปต์ทุบตีปฏิบัติการได้ด้วยเครื่องหมายทับหรือไม่มี


2

ฉันมีสคริปต์ทุบตีtest.shซึ่งไม่ทำอะไรเป็นพิเศษ:

#!/bin/bash
echo Hello!

ถ้าฉันเรียกใช้เช่นนี้. test.shมันใช้งานได้

kopparberg:dev marek$ . test.sh
Hello!

ถ้าฉันเรียกใช้เช่นนี้./test.shมันไม่ได้

kopparberg:dev marek$ ./test.sh 
-bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory

อะไรคือความแตกต่าง?

คำตอบ:


5

ความแตกต่างระหว่างการจัดหา ( . test.sh) สคริปต์และการเรียกใช้ ( test.shหรือ./test.sh) อยู่ในบรรทัดแรก

หากคุณแหล่งสคริปต์บรรทัดแรกเป็นเพียงความคิดเห็นและละเว้น แต่ถ้าคุณเรียกใช้บรรทัดแรกจะถูกตรวจสอบโดยเคอร์เนลสำหรับอักขระสองตัวแรกและถ้าเป็น " #!" ส่วนที่เหลือของบรรทัดจะถูกใช้เป็นพา ธ และอาร์กิวเมนต์แรกสำหรับล่าม นั่นคือเคอร์เนลจะมองหาไฟล์ที่เรียกใช้งานได้/bin/bashและส่งชื่อของสคริปต์เป็นอาร์กิวเมนต์แรก /bin/bash ./test.shเช่นนี้

นี่คือสิ่งที่จะเกิดขึ้นตามปกติและคุณพูดถูกมันควรจะมีผลเช่นเดียวกันกับสคริปต์ของคุณ แต่สคริปต์ของคุณมีปัญหา: บรรทัดแรกจบลงด้วยการสิ้นสุดบรรทัด DOS (CR LF) แทนการสิ้นสุดบรรทัดยูนิกซ์ (LF) ดังนั้นชื่อของล่ามตามที่เคอร์เนลเห็นว่ามัน/bin/bash^Mไม่มีอยู่ในดิสก์ของคุณ (^ M ย่อมาจาก spurious CR ก่อนการสิ้นสุดบรรทัด) เพื่อทำให้เรื่องแย่ลงตัวละคร ^ M มักจะมองไม่เห็น

คุณสามารถพิสูจน์ได้ว่าเป็นกรณีนี้ด้วยcat -v test.sh(ซึ่งพิมพ์การทดแทน ^ M สำหรับอักขระ CR ที่มองไม่เห็น)


2

โซลูชันกำปั้นคือนามแฝงสำหรับคำสั่ง "แหล่งที่มา"

shebangถือว่าเหมือน #comment สำหรับแหล่งที่มา

เมื่อคุณเรียกใช้สคริปต์ด้วย./scriptเชลล์จะดำเนินการสคริปต์ด้วยshebang #!/bin/bash

ข้อผิดพลาดที่คุณให้ดูเหมือนจะเป็นปัญหา CRLF คุณสามารถเรียกใช้:

dos2unix script.sh

เพื่อลบบรรทัดสุดท้ายของ Windows

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.