ดังนั้นฉันคิดว่าฉันมีความเข้าใจที่ดีในเรื่องนี้ แต่เพียงแค่ทดสอบ (เพื่อตอบสนองต่อการสนทนาที่ฉันไม่เห็นด้วยกับใครบางคน) และพบว่าความเข้าใจของฉันมีข้อบกพร่อง ...
ในรายละเอียดมากที่สุดจะเกิดอะไรขึ้นเมื่อฉันเรียกใช้ไฟล์ในเชลล์? สิ่งที่ฉันหมายถึงคือถ้าฉันพิมพ์: ./somefile some arguments
ลงในเปลือกของฉันและกดย้อนกลับ (และsomefile
มีอยู่ใน cwd และฉันได้อ่าน + ดำเนินการสิทธิ์บนsomefile
) แล้วเกิดอะไรขึ้นภายใต้ประทุน?
ฉันคิดว่าคำตอบคือ:
- เปลือกทำ syscall ให้
exec
ผ่านเส้นทางไปsomefile
- เคอร์เนลตรวจสอบ
somefile
และดูหมายเลขมายากลของไฟล์เพื่อตรวจสอบว่าเป็นรูปแบบที่โปรเซสเซอร์สามารถจัดการได้หรือไม่ - หากหมายเลขมายากลระบุว่าไฟล์อยู่ในรูปแบบที่โปรเซสเซอร์สามารถใช้งานได้
- กระบวนการใหม่ถูกสร้างขึ้น (โดยมีรายการในตารางกระบวนการ)
somefile
ถูกอ่าน / แมปกับหน่วยความจำ สแต็กถูกสร้างขึ้นและการดำเนินการข้ามไปยังจุดเริ่มต้นของรหัสsomefile
โดยARGV
เริ่มต้นไปที่อาร์เรย์ของพารามิเตอร์ (achar**
,["some","arguments"]
)
- หากจำนวนมายากลเป็นshebangแล้ว
exec()
spawns กระบวนการใหม่ดังกล่าวข้างต้น แต่ปฏิบัติการที่ใช้เป็นล่ามอ้างอิงโดย shebang (เช่น/bin/bash
หรือ/bin/perl
) และsomefile
ถูกส่งไปยังSTDIN
- หากไฟล์ไม่มีหมายเลขเวทย์มนตร์ที่ถูกต้องแสดงว่ามีข้อผิดพลาดเช่น "ไฟล์ไม่ถูกต้อง (หมายเลขเวทย์มนตร์ที่ไม่ดี): เกิดข้อผิดพลาดในรูปแบบ Exec"
อย่างไรก็ตามมีคนบอกฉันว่าถ้าไฟล์เป็นข้อความธรรมดาเชลล์จะพยายามเรียกใช้คำสั่ง (เช่นถ้าฉันพิมพ์bash somefile
) ฉันไม่เชื่อเรื่องนี้ แต่ฉันแค่ลองมันและมันก็ถูกต้อง ดังนั้นฉันจึงมีความเข้าใจผิดอย่างชัดเจนเกี่ยวกับสิ่งที่เกิดขึ้นจริงที่นี่และต้องการที่จะเข้าใจกลไก
จะเกิดอะไรขึ้นเมื่อฉันเรียกใช้ไฟล์ในเชลล์ (ในรายละเอียดมากพอสมควร ... )
source somefile
จะแตกต่างจากกระบวนการใหม่ถูกง่ามปิดโดย./somefile
แม้ว่า
./somefile
มันจะทำให้ bash รันคำสั่งsomefile
หากไฟล์ไม่มีหมายเลขเวทย์มนตร์ ฉันคิดว่ามันจะแสดงข้อผิดพลาดและดูเหมือนจะมีประสิทธิภาพแทนsource somefile
somefile
เป็นไฟล์ข้อความจากนั้นเชลล์ใหม่จะเกิดขึ้นถ้าฉันพยายามเรียกใช้งาน ไฟล์echo $$
ทำงานแตกต่างกันหากฉันเรียกใช้ vs source มัน