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
?.
Isso é configurado por meio do mecanismo binfmt_misc . A interface para o mecanismo está em
/proc/sys/fs/binfmt_misc
. Há também o diretório de configuração/etc/binfmt.d
quesystemd-binfmt.service
lê.Na minha máquina, o
/etc/binfmt.d
diretório está vazio, então não é isso. Quando eu verifico abaixo,/proc/sys/
recebo:Sem qualquer entendimento do mecanismo de como isso foi feito ou quais são todas as opções de configuração, isso é bem óbvio. Ele diz que "CLR" está "habilitado" para "interpretador /usr/bin/mono" identificado por "magic 4d5a". Pode-se verificar que os caracteres 0x4d 0x5a são "MZ" facilmente.
A instalação de um dos pacotes deve ter executado um script de instalação que definiu isso. Não estou claro sobre o mecanismo para isso, mas deve estar no link acima.
EDITAR:
Como um comentarista apontou aqui, há um
/usr/lib/binfmt.d
diretório. Acabei de verificar, e na minha máquina o único arquivo lá agora é ummono.conf
que é claramente isso. O conteúdo é:o que é bastante autoexplicativo.