Uczę się języka C #, więc stworzyłem mały program w języku C #, który mówi Hello, World!
, a następnie skompilowałem go mono-csc
i uruchomiłem z mono
:
$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!
Zauważyłem, że kiedy uderzy TAB
w bash
, Hello.exe
cechował wykonywalny. Rzeczywiście, działa tylko przez powłokę ładującą nazwę pliku!
Hello.exe
to nie jest plik ELF z zabawnym rozszerzenie pliku:
$ 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
oznacza, że jest to plik wykonywalny połączony statycznie z Microsoft Windows. Upuść go w oknie systemu Windows i będzie (powinien) działać.
Mam wine
zainstalowany, ale wine
będąc warstwa kompatybilności z aplikacjami Windows trwa około 5x tak długo, aby uruchomić Hello.exe
jak mono
i wykonywanie go bezpośrednio nie, więc nie jest to wine
, że prowadzi go.
Zakładam, że jest mono
zainstalowany moduł jądra, mono
który przechwytuje exec
syscall / s lub przechwytuje pliki binarne, które zaczynają się od 4D 5A
, ale lsmod | grep mono
znajomi zwracają błąd.
Co się tutaj dzieje i skąd jądro wie, że ten plik wykonywalny jest wyjątkowy?
Na dowód, że to nie moja magia działająca w powłoce, użyłem Crap Shell (aka sh
), aby ją uruchomić i nadal działa natywnie.
Oto pełny program, ponieważ komentator był ciekawy:
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
, w twoim przypadku program jest mono, podczas gdy moje przykłady obejmują php, python, perl i java. Podejrzewam, czy mono zezwala na rozszerzenie pliku innego niż .exe nadal wykonywanego za pomocą kodu. Nie powinno to wcale zależeć od systemu Windows, ponieważ w końcu jest to wykonywany skompilowany kod. Jednak jeśli plik źródłowy ma jakiś kod zależny, taki jak interfejsy API systemu Windows, to oczywiście potrzebujesz wina do uruchomienia tego pliku exe.
/etc/magic
lub /usr/share/file/magic
(lub podobna magiczna lokalizacja) to plik zawierający informacje niezbędne do tego, aby to zrobić.
$ foo.jar
zamiast $ java -jar foo.jar
- podobnie jak w przypadku mono.
php hello.php
lubpython hello.py
lubperl hello.pl
lub w przypadku skompilowanego języka takiego jak javajava hello
, uruchomiliby się również, ponieważ nie są tam wykonywalne, ale program odczytuje i wykonuje plik. Jeśli jednak uruchomisz./hello.exe
zamiastmono hello.exe
, znalazłem twoje pytanie i zaakceptowałem bardziej sensowną odpowiedź (która w przypadku zdecydowanie skorzysta z obsługi binfmt.