ฉันกำลังเรียนรู้ C # ดังนั้นฉันจึงทำโปรแกรม C # เล็ก ๆ ที่กล่าวHello, World!แล้วรวบรวมmono-cscและเรียกใช้ด้วยmono:
$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!
ผมสังเกตเห็นว่าเมื่อฉันตีTABในbash, Hello.exeถูกทำเครื่องหมายปฏิบัติการ อันที่จริงมันทำงานโดยเพียงแค่โหลดเปลือกชื่อไฟล์!
Hello.exeคือไม่ได้เป็นแฟ้มเอลฟ์ที่มีนามสกุลไฟล์ตลก:
$ readelf -a Hello.exe
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
$ xxd Hello.exe | head -n1
00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ..............
MZหมายความว่าเป็น Microsoft Windows ที่เชื่อมโยงแบบคงที่ปฏิบัติการได้ วางลงในกล่อง Windows และมันจะ (ควร) ทำงาน
ผมได้wineติดตั้ง แต่wineเป็นชั้นเข้ากันได้สำหรับปพลิเคชันของ Windows จะใช้เวลาประมาณ 5 เท่าเป็นเวลานานเพื่อให้ทำงานHello.exeเป็นmonoและดำเนินการโดยตรงไม่ดังนั้นจึงไม่ได้wineว่ามันวิ่ง
ฉันสมมติว่ามีบางmonoเคอร์เนลโมดูลที่ติดตั้งกับmonoที่จุดตัดexecsyscall / s หรือจับไบนารีที่ขึ้นต้นด้วย4D 5Aแต่lsmod | grep monoเพื่อน ๆ กลับข้อผิดพลาด
เกิดอะไรขึ้นที่นี่และเคอร์เนลรู้ได้อย่างไรว่าไฟล์ปฏิบัติการนี้มีความพิเศษ?
เพื่อพิสูจน์ว่ามันไม่ใช่เวทย์มนตร์ของเปลือกหอยฉันใช้Crap Shell (aka sh) เพื่อเรียกใช้และมันก็ยังทำงานได้ตามปกติ
นี่คือโปรแกรมเต็มรูปแบบเนื่องจากผู้แสดงความคิดเห็นอยากรู้อยากเห็น:
using System;
class Hello {
/// <summary>
/// The main entry point for the application
/// </summary>
[STAThread]
public static void Main(string[] args) {
System.Console.Write("Hello, World!\n");
}
}
program codefileในกรณีที่โปรแกรมของคุณเป็นขาวดำในขณะที่ตัวอย่างของฉันมี php, python, perl และ java ฉันสงสัยว่า mono อนุญาตให้มีการขยายไปยังไฟล์อื่นที่ไม่ใช่. exe หรือยังถูกเรียกใช้งานผ่านโค้ด ไม่ควรขึ้นอยู่กับหน้าต่างเลยเพราะนี่คือรหัสที่คอมไพล์แล้ว อย่างไรก็ตามหากไฟล์ต้นฉบับของคุณมีโค้ดที่ขึ้นต่อกันเช่น API เฉพาะของ Windows คุณต้องมีไวน์สำหรับการเรียกใช้ไฟล์ exe นั้น
/etc/magicหรือ/usr/share/file/magic(หรือตำแหน่งเวทมนตร์ที่คล้ายกัน) เป็นไฟล์ที่มีข้อมูลที่จำเป็นในการทำเช่นนี้
$ foo.jarมากกว่า$ java -jar foo.jar- คล้ายกับสิ่งที่ทำสำหรับโมโน
php hello.phpหรือpython hello.pyหรือperl hello.plในกรณีของภาษาที่คอมไพล์อย่าง javajava helloพวกเขาก็จะเรียกใช้เนื่องจากไม่มีการปฏิบัติการ แต่โปรแกรมอ่านและเรียกใช้ไฟล์ อย่างไรก็ตามถ้าคุณเรียกใช้./hello.exeแทนmono hello.exeฉันพบคำถามของคุณและยอมรับคำตอบที่สมเหตุสมผลมากขึ้น (ซึ่งในกรณีที่ใช้ binfmt-support อย่างแน่นอน