ฉันกำลังเรียนรู้ 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
ที่จุดตัดexec
syscall / 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 อย่างแน่นอน