Recentemente, tive que construir um programa que eu precisava a partir do código-fonte que obtive no GitHub. O programa era uma porta Linux de um programa Windows escrito em C#. Consegui descobrir os pacotes que eu precisava, como dotnet-runtime
e dotnet-sdk
, junto com alguns outros como nuget
, mono
, e mono-msbuild
. Eu construí e instalei o programa em /opt
.
Dei uma olhada nos internos. Há um link abaixo /usr/local/bin/
para um script de shell em /opt/program/bin/
. O script de shell executa o /opt/program/bin/Program.exe
executável. Isso é o que eu esperava, porque é um executável do Windows, exceto que então percebi que ele foi executado (após mudar para o diretório do projeto) com um comando como
exec bin/Program.Exe
o que implica que ele não está sendo executado como um argumento para outro programa. Essa não era minha expectativa. Eu esperaria que o Linux precisasse de um programa de supervisão para executar um exe do Windows, como o que é necessário para Java (ou o que algo como Wine faz com um verdadeiro programa do Windows).
Então verifiquei que poderia executar o programa diretamente com
$ /opt/program/bin/Program.exe
Então dei uma olhada no arquivo e, com certeza, ele de fato começa com MZ
os dois primeiros bytes, então verifiquei
$ file /opt/program/bin/Program.exe
/opt/program/bin/Program.exe: PE32 executable for MS Windows 4.00 (GUI), Intel i386 Mono/.Net assembly, 3 sections
$
Então, este é definitivamente um executável do MS Windows. Para completar, eu fiz uma busca rápida e os mecanismos de busca responderam que o Linux não roda executáveis do Windows nativamente (eu sabia disso, é claro).
A única coisa que consigo pensar para explicar isso é que quando você instala o dotnet-runtime
pacote, algum tipo de alteração é feita para informar ao kernel como executá-lo, semelhante à regra do kernel para executáveis que começam com #!/path/to/interpreter
?.