ดังนั้นฉันคิดว่าฉันมีความเข้าใจที่ดีในเรื่องนี้ แต่เพียงแค่ทดสอบ (เพื่อตอบสนองต่อการสนทนาที่ฉันไม่เห็นด้วยกับใครบางคน) และพบว่าความเข้าใจของฉันมีข้อบกพร่อง ...
ในรายละเอียดมากที่สุดจะเกิดอะไรขึ้นเมื่อฉันเรียกใช้ไฟล์ในเชลล์? สิ่งที่ฉันหมายถึงคือถ้าฉันพิมพ์: ./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 มัน