我正在学习C#,所以我做了一个小程序,说Hello, World!,然后用mono-csc编译并用mono运行:

$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!


我注意到在TAB中命​​中bashHello.exe被标记为可执行。确实,它仅由一个加载文件名的外壳运行!

Hello.exe不是带有有趣文件扩展名的ELF文件:

$ 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和朋友返回错误。

这是怎么回事,内核如何知道该可执行文件是特殊的?废话说Shell(aka Hello.exe)运行它,它仍然可以在本机运行。


由于评论者好奇,这里是完整的程序:

 mono 


评论

当您得到答案时,但是我有点困惑,如果您运行诸如php hello.php或python hello.py或perl hello.pl之类的命令,或者在诸如Java java hello之类的编译语言的情况下,它们也将运行,因为可执行文件,但有程序读取并执行文件。但是,如果您运行./hello.exe而不是mono hello.exe,则我发现了您的问题并接受了更合理的答案(以防万一,请务必使用binfmt-support。

@ kuldeep.kamboj我不确定我是否理解您的意思,但我只是惊讶Windows可执行文件在Linux机器上“本地”运行。

实际上,我所说的是,任何代码文件(或编译文件)都可以通过其程序以程序代码文件格式执行,在您的情况下,程序是mono,而我的示例包括php,python,perl和java。我怀疑单声道是否允许通过.exe文件扩展到.exe文件以外的文件。它不应该完全依赖于Windows,因为这最终是执行编译的代码。但是,如果源文件具有某些依赖代码,例如仅Windows API,则显然您必须需要wine才能运行该exe文件。

具有讽刺意味的是,/ etc / magic或/ usr / share / file / magic(或类似的魔术位置)是包含能够执行此操作所需信息的文件。

@cat是一个非常有趣的文件(如果我要收藏一个文件,那可能是我的首选)。它具有识别各种文件的信息。但是,在确定如何运行文件之前,您需要先确定文件是什么。这就是文件及其作用所在。类似的事情-Java二进制内核对Linux的支持由来已久,因此您可以执行$ foo.jar而不是$ java -jar foo.jar-与对mono所做的类似。

#1 楼

这实际上是binfmt_misc:它允许内核被告知如何运行未知的二进制文件。看一下/proc/sys/fs/binfmt_misc的内容;在您看到的文件中,应该解释一下如何运行Mono二进制文件:

enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a


(在Debian系统上)。这告诉内核,应将以MZ4d5a)开头的二进制文件分配给run-detectors。后者指出是使用Mono还是Wine运行二进制文件。

二进制类型可以随时添加,删除,启用和禁用;有关详细信息,请参见上面的文档(语义令人惊讶,此处使用的虚拟文件系统的行为并不完全类似于标准文件系统)。 /proc/sys/fs/binfmt_misc/status给出全局状态,每个二进制“描述符”显示其各自的状态。禁用binfmt_misc的另一种方法是卸载其内核模块(如果它是作为模块构建的)。

此功能允许支持新的二进制类型,例如MZ可执行文件(包括Windows PE和PE +二进制文件,以及DOS和OS / 2个二进制文件!),Java JAR文件……它还允许已知的二进制类型在新的体系结构上受支持,通常使用Qemu;因此,有了适当的库,您就可以在Intel处理器上透明地运行ARM Linux二进制文件!

您的问题源于交叉编译,尽管在.NET方面如此,这对binfmt_misc提出了警告。注意:当您尝试在可以运行交叉编译的二进制文件的系统上交叉编译时,某些配置脚本的行为不正确。通常,检测交叉编译涉及构建二进制文件并尝试运行它。如果运行,则您不会交叉编译,否则,您就交叉编译了(或编译器坏了)。在这种情况下,通常可以通过显式指定构建和宿主体系结构来修复autoconf脚本,但是有时您必须暂时禁用binfmt_misc ...

评论


对于那些对/ proc感兴趣的人,您可能会对/ proc / *的工作方式感兴趣?在超级用户上。

–用户
16-2-5在9:22