ความแตกต่างระหว่างการจัดหา ( . 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 ที่มองไม่เห็น)