Eu sei que certos processadores são Big Endian e outros são Little Endian. Mas existe um comando, script bash, script python ou série de comandos que podem ser usados na linha de comando para determinar se um sistema é Big Endian ou Little Endian? Algo como:
if <some code> then
echo Big Endian
else
echo Little Endian
fi
Ou é mais simples determinar apenas qual processador o sistema está usando e acompanhá-lo para determinar sua Endianess?
central-processing-unit
Jake Wilson
fonte
fonte
Respostas:
Em um sistema Big Endian (Solaris em SPARC)
0 0
Em um pequeno sistema endian (Linux on x86)
1
A solução acima é inteligente e funciona muito bem para Linux * 86 e Solaris Sparc.
Eu precisava de uma solução somente de shell (sem Perl) que também funcionasse no AIX / Power e HPUX / Itanium. Infelizmente, os dois últimos não são bons: o AIX reporta "6" e o HPUX fornece uma linha vazia.
Usando sua solução, pude criar algo que funcionasse em todos esses sistemas Unix:
$ echo I | tr -d [:space:] | od -to2 | head -n1 | awk '{print $2}' | cut -c6
Em relação à solução Python que alguém postou, ela não funciona no Jython porque a JVM trata tudo como Big. Se alguém puder fazê-lo funcionar em Jython, por favor poste!
Além disso, eu achei isso, o que explica o endianness de várias plataformas. Alguns hardwares podem operar nos dois modos, dependendo do que o sistema operacional seleciona: http://labs.hoffmanlabs.com/node/544
Se você usar o awk, esta linha poderá ser simplificada para:
Para pequenas caixas Linux que não possuem 'od' (por exemplo, OpenWrt), tente 'hexdump':
fonte
I
(olho) ao invés de minúsculal
(ell).printf "\x1" | od -to2 | awk 'NR==1{print$2==1}'
Se você estiver em uma máquina Linux bastante recente (quase tudo depois de 2012) ,
lscpu
agora contém essas informações:Isso foi adicionado
lscpu
na versão 2.19, que é encontrada no Fedora> = 17, CentOS> = 6.0, Ubuntu> = 12.04.Note que eu encontrei esta resposta a partir de esta resposta óptimo em Unix.SE . Essa resposta tem muitas informações relevantes, este post é apenas um resumo.
fonte
Aqui está um script python de uma linha mais elegante
código de saída
0
significa big endian e1
significa little endianou simplesmente mude
sys.exit
paraprint
para uma saída imprimívelfonte
python -c "import sys;sys.exit(int(sys.byteorder!='big'))"
A resposta principal pode ser simplificada levemente usando
awk
:Em um sistema Big Endian (Solaris, SPARC)
Em um sistema Little Endian (Linux, Intel)
Kernels Linux mais recentes
A partir da versão 2.19 do pacote util-linux, o comando
lscpu
começou a incluir um campo relacionado ao Endianness. Então agora você pode simplesmente usar este comando para descobrir isso:Isso foi confirmado no Ubuntu 12.10 e CentOS 6. Portanto, eu estaria disposto a assumir que a maioria dos Kernels do Linux 3.0+ está oferecendo isso agora.
Nos sistemas Debian / Ubuntu, você também pode usar este comando, sem ter certeza de quando ele ficou disponível:
Referências
fonte
Este script Python deve funcionar para você:
fonte
python -c "from struct import pack;import sys;sys.exit(int(pack('@h',1)==pack('<h',1)))"
. O código de saída é 0 para big endian e 1 para little endian.Seria imprimir a endianess do sistema.
fonte
Você pode tirar proveito do formato de arquivo ELF para determinar a resistência do seu sistema. Por exemplo, imprima os seis primeiros bytes de um arquivo ELF arbitrário em hexadecimal:
xxd -c 1 -l 6 /bin/ls
0000000: 7f . 0000001: 45 E 0000002: 4c L 0000003: 46 F 0000004: 02 . 0000005: 01 .
Se a última linha (o byte de seis dígitos) for 01, de acordo com o formato ELF , 01 é little endian e 02 é big endian.
Se você não tiver um
xxd
na sua caixa (e tiver o busybox), tente o seguinte:hexdump -s 5 -n 1 -C /bin/busybox
fonte
Eu encontrei uma maneira de fazer isso no Jython. Como o Jython (Python na JVM) é executado em uma VM, ele sempre reporta big endian, independentemente do hardware.
Esta solução funciona para Linux, Solaris, AIX e HPUX. Não testou no Windows:
fonte
Um comando de linha única baseado no formato ELF:
hexdump -s 5 -n 1 /bin/sh
fonte
Requisito ligeiramente diferente: preciso de um teste como este em um script de configuração de compilação do programa para determinar se a máquina de destino de compilação é pouco ou pouco endian, sem executar código . O script deve depositar
#define HAVE_LITTLE_ENDIAN 1
em umconfig.h
cabeçalho, ou então#define HAVE_LITTLE_ENDIAN 0
.A máquina de destino de compilação pode ser diferente da máquina de compilação, pois podemos fazer uma compilação cruzada, o que também explica por que o teste não deve tentar executar nenhum código compilado. Está fora de cogitação ter um pequeno programa C com uma
printf
declaração que cuspa a resposta.Uma solução possível é essa. Geramos um arquivo chamado
conftest.c
que contém este:Agora, compilamos isso para
conftest.o
usar:Então nós corremos:
Se a string
PSILXINUEROCMIWD
ocorrer, o destino é little-endian. Se a stringLISPUNIXCOREDWIM
ocorrer, é big-endian. Se nenhuma string ocorrer ou, ainda mais surpreendente, as duas ocorrerem, o teste falhou.Essa abordagem funciona porque as constantes "fourcc" calculadas no programa têm valores independentes da máquina, denotando os mesmos números inteiros, independentemente da endianidade. Sua representação de armazenamento no arquivo de objeto segue o endianness do sistema de destino e é visível através da exibição baseada em caracteres em
strings
.As duas palavras de proteção zero garantem que a string seja isolada. Isso não é estritamente necessário, mas garante que a sequência que estamos procurando não seja incorporada em outra sequência, o que significa que
strings
a saída será feita em uma linha por si só.PS, a
USPELL
macro não coloca parênteses nas inserções de argumento, porque é criada para esse fim específico, não para reutilização.fonte