Я изучаю C #, поэтому я создал небольшую программу на C #, которая говорит Hello, World!
, затем скомпилировал ее mono-csc
и запустил mono
:
$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!
Я заметил , что когда я попал TAB
в bash
, Hello.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
, будучи уровень совместимости для приложений Windows, занимает около 5х до тех пор , запускать , Hello.exe
как mono
и выполнение его непосредственно делать, так что это не wine
что запускает его.
Я предполагаю, что установлен какой-то mono
модуль ядра, mono
который перехватывает exec
системный вызов / s или перехватывает двоичные файлы, которые начинаются с 4D 5A
, но lsmod | grep mono
друзья возвращают ошибку.
Что здесь происходит, и как ядро узнает, что этот исполняемый файл особенный?
Просто для доказательства , что это не моя оболочка работает магия, я использовал гречиху Shell (он же 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");
}
}
php hello.php
илиpython hello.py
или,perl hello.pl
или в случае скомпилированного языка, такого как java,java hello
они также будут запускаться, так как они там не исполняемые, а программа чтения и выполнения файла. Однако, если вы запустите./hello.exe
вместо того,mono hello.exe
чтобы я нашел ваш вопрос и принял более разумный ответ (который в случае обязательно использовать binfmt-support.program codefile
, в вашем случае программа моно, в то время как мои примеры включают php, python, perl и java. Я подозреваю, если моно разрешить расширение, отличное от .exe файла, все еще выполняется с помощью кода. Он вообще не должен зависеть от окон, так как, наконец, это выполнение скомпилированного кода. Однако, если ваш исходный файл имеет некоторый зависимый код, такой как API только для Windows, тогда, очевидно, вам нужно Wine для запуска этого exe-файла./etc/magic
или/usr/share/file/magic
(или подобное магическое место) - это файл, который содержит информацию, необходимую для того, чтобы это сделать.$ foo.jar
а не$ java -jar foo.jar
- похоже на то, что делается для моно.Ответы:
Это binfmt_misc в действии: он позволяет ядру сказать, как запускать двоичные файлы, о которых он не знает. Посмотрите на содержимое
/proc/sys/fs/binfmt_misc
; среди файлов, которые вы там видите, нужно объяснить, как запускать Mono binaries:(в системе Debian). Это говорит ядру, что двоичные файлы, начинающиеся с
MZ
(4d5a
), должны быть переданыrun-detectors
. Последний выясняет, использовать ли Mono или Wine для запуска двоичного файла.Двоичные типы могут быть добавлены, удалены, включены и отключены в любое время; подробности смотрите в документации выше (семантика удивительна, используемая здесь виртуальная файловая система не ведет себя полностью как стандартная файловая система).
/proc/sys/fs/binfmt_misc/status
дает глобальный статус, и каждый двоичный «дескриптор» показывает свой индивидуальный статус. Другой способ отключенияbinfmt_misc
- выгрузить модуль ядра, если он собран как модуль; это также означает, что можно занести его в черный список, чтобы полностью избежать.Эта функция позволяет поддерживать новые двоичные типы, такие как исполняемые файлы MZ (включая двоичные файлы Windows PE и PE +, а также двоичные файлы DOS и OS / 2!), Файлы JAR Java ... Она также позволяет поддерживать известные двоичные типы на новые архитектуры, обычно использующие Qemu; таким образом, с соответствующими библиотеками вы можете прозрачно запускать двоичные файлы ARM Linux на процессоре Intel!
Ваш вопрос возник из-за кросс-компиляции, хотя и в смысле .NET, и это вызывает оговорку
binfmt_misc
: некоторые скрипты конфигурации ведут себя неправильно, когда вы пытаетесь кросс-компилировать в системе, которая может запускать кросс-компилированные двоичные файлы. Как правило, обнаружение кросс-компиляции включает сборку двоичного файла и попытку его запуска; если он работает, вы не выполняете кросс-компиляцию, если это не так, то вы (или ваш компилятор не работает).autoconf
в этом случае сценарии обычно можно исправить, явно указав архитектуру сборки и хоста, но иногда вам придетсяbinfmt_misc
временно отключить ...источник