it-swarm.com.de

Wie kann man feststellen, ob ein Linux-System Big Endian oder Little Endian ist?

Ich weiß, dass bestimmte Prozessoren Big Endian und andere Little Endian sind. Aber gibt es einen Befehl, ein Bash-Skript, python Skript oder eine Reihe von Befehlen, die in der Befehlszeile verwendet werden können, um festzustellen, ob ein System Big Endian oder Little Endian ist?

if <some code> then
    echo Big Endian
else
    echo Little Endian
fi

Oder ist es einfacher, einfach zu bestimmen, welchen Prozessor das System verwendet, und damit die Endianess zu bestimmen?

95
Jake Wilson

Auf einem Big Endian-System (Solaris auf SPARC)

$ echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6 

Auf einem kleinen Endian-System (Linux auf x86)

$ echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6 

1


Die obige Lösung ist clever und funktioniert hervorragend für Linux * 86 und Solaris Sparc.

Ich brauchte eine reine Shell-Lösung (kein Perl), die auch unter AIX/Power und HPUX/Itanium funktioniert. Leider spielen die letzten beiden nicht Nizza: AIX meldet "6" und HPUX gibt eine leere Zeile aus.

Mit Ihrer Lösung konnte ich etwas erstellen, das auf all diesen Unix-Systemen funktioniert:

$ echo I | tr -d [:space:] | od -to2 | head -n1 | awk '{print $2}' | cut -c6

In Bezug auf die Python -Lösung, die jemand gepostet hat, funktioniert sie in Jython nicht, da die JVM alles als groß behandelt. Wenn jemand sie in Jython zum Laufen bringen kann, posten Sie sie bitte!

Außerdem habe ich dies gefunden, was die Endianness verschiedener Plattformen erklärt. Einige Hardware kann in beiden Modi betrieben werden, je nachdem, was das Betriebssystem auswählt: http://labs.hoffmanlabs.com/node/544


Wenn Sie awk verwenden, kann diese Zeile vereinfacht werden, um:

echo -n I | od -to2 | awk '{ print substr($2,6,1); exit}'

Für kleine Linux-Boxen ohne 'od' (sagen wir OpenWrt) versuchen Sie 'hexdump':

echo -n I | hexdump -o | awk '{ print substr($2,6,1); exit}'
114
krissi

Wenn Sie sich auf einem relativ neuen Linux-Computer befinden (fast alles nach 2012) , enthält lscpu jetzt folgende Informationen:

$ lscpu | grep Endian
Byte Order:            Little Endian

Dies wurde zu lscpu in Version 2.19 hinzugefügt, die in Fedora> = 17, CentOS> = 6.0, Ubuntu> = 12.04 enthalten ist.

Beachten Sie, dass ich diese Antwort von diese großartige Antwort unter Unix.SE gefunden habe. Diese Antwort enthält viele relevante Informationen. Dieser Beitrag ist nur eine Zusammenfassung.

40
dotancohen

Hier ist ein eleganteres python einzeiliges Skript

python -c "import sys;sys.exit(0 if sys.byteorder=='big' else 1)"

exit-Code 0 bedeutet Big Endian und 1 bedeutet Little Endian

oder einfach ändern sys.exit bis print für eine druckbare Ausgabe

32
mchurichi

Sie können das ELF-Dateiformat nutzen, um die Endianness Ihres Systems zu bestimmen. Drucken Sie beispielsweise die ersten sechs Bytes einer beliebigen ELF-Datei in hexadezimaler Form:

xxd -c 1 -l 6 /bin/ls

0000000: 7f . 0000001: 45 E 0000002: 4c L 0000003: 46 F 0000004: 02 . 0000005: 01 .

Wenn die letzte Zeile (das Sechserbyte) gemäß ELF-Format 01 ist, ist 01 Little Endian und 02 ist Big Endian.

Wenn Sie kein xxd auf Ihrer Box haben (und eine Busybox haben), versuchen Sie Folgendes:

hexdump -s 5 -n 1 -C /bin/busybox

10
Tong Zhou

Die Hauptantwort kann mit awk leicht vereinfacht werden:

Auf einem Big Endian-System (Solaris, SPARC)

$ echo -n I | od -to2 | awk 'FNR==1{ print substr($2,6,1)}'
0

Auf einem Little Endian-System (Linux, Intel)

$ echo -n I | od -to2 | awk 'FNR==1{ print substr($2,6,1)}'
1

Neuere Linux-Kernel

Ab Version 2.19 des util-linux-Pakets wurde der Befehl lscpu mit einem Feld für Endianness gestartet. Jetzt können Sie einfach diesen Befehl verwenden, um dies herauszufinden:

$ lscpu | grep -i byte
Byte Order:            Little Endian

Dies wurde unter Ubuntu 12.10 und CentOS 6 bestätigt. Daher würde ich davon ausgehen, dass die meisten 3.0+ Linux-Kernel dies jetzt anbieten.

Auf Debian/Ubuntu-Systemen können Sie diesen Befehl auch verwenden, ohne sicher zu sein, wann er verfügbar wurde:

$ dpkg-architecture | grep -i end
DEB_BUILD_Arch_ENDIAN=little
DEB_Host_Arch_ENDIAN=little

Verweise

10
slm

Dieses Python Skript sollte für Sie funktionieren:

#!/usr/bin/env python
from struct import pack
if pack('@h', 1) == pack('<h', 1):
    print "Little Endian"
else:
    print "Big Endian"
python -c "import sys; print(sys.byteorder)"

Es würde die Endianness des Systems drucken.

7
prembhaskal

Ich habe einen Weg gefunden, dies in Jython zu tun. Da Jython (Python auf der JVM) auf einer VM ausgeführt wird, wird unabhängig von der Hardware immer Big Endian gemeldet.

Diese Lösung funktioniert unter Linux, Solaris, AIX und HPUX. Habe nicht unter Windows getestet:

    from Java.lang import System
    for property, value in dict(System.getProperties()).items():
        if property.endswith('cpu.endian'):
            return value
3
Foo

Ein einzeiliger Befehl basierend auf dem ELF-Format:
hexdump -s 5 -n 1 /bin/sh

2
fae

Etwas andere Anforderung: Ich benötige einen Test wie diesen in einem Programmbuild-Konfigurationsskript, um festzustellen, ob Zielcomputer kompilieren Bit oder Little Endian ist, ohne Code auszuführen. Das Skript muss #define HAVE_LITTLE_ENDIAN 1 in ein config.h Header oder sonst #define HAVE_LITTLE_ENDIAN 0.

Der Kompilierungszielcomputer unterscheidet sich möglicherweise vom Buildcomputer, da wir möglicherweise Cross-Compilieren. Dies erklärt auch, warum der Test nicht versuchen darf, kompilierten Code auszuführen. Es kommt nicht in Frage, ein kleines C-Programm mit einer printf -Anweisung zu haben, die die Antwort ausspuckt.

Eine mögliche Lösung ist dies. Wir generieren eine Datei namens conftest.c das enthält:

#define USPELL(C0, C1, C2, C3) \                                             
  ((unsigned) C0 << 24 | \                                              
   (unsigned) C1 << 16 | \                                              
   (unsigned) C2 << 8 | (unsigned) C3)                                       

unsigned x[6] = {                                                       
  0,                                                                         
  USPELL('L', 'I', 'S', 'P'),                                                
  USPELL('U', 'N', 'I', 'X'),                                                
  USPELL('C', 'O', 'R', 'E'),                                                
  USPELL('D', 'W', 'I', 'M'),                                                
  0                                                                          
};

Nun kompilieren wir dies zu conftest.o using:

$ /path/to/cross-compiling/cc conftest.c -c

Dann rennen wir:

$ strings conftest.o
PSILXINUEROCMIWD

Wenn die Zeichenfolge PSILXINUEROCMIWD vorkommt, ist das Ziel Little-Endian. Wenn die Zeichenfolge LISPUNIXCOREDWIM vorkommt, handelt es sich um Big-Endian. Wenn keine Zeichenfolge auftritt oder, noch erstaunlicher, beide, ist der Test fehlgeschlagen.

Dieser Ansatz funktioniert, weil die im Programm berechneten "fourcc" -Konstanten maschinenunabhängige Werte haben, die unabhängig von der Endianness dieselben ganzen Zahlen bezeichnen. Ihre Speicherdarstellung in der Objektdatei folgt der Endianness des Zielsystems und ist über die zeichenbasierte Ansicht unter strings sichtbar.

Die zwei Nullschutzwörter stellen sicher, dass die Zeichenfolge isoliert ist. Dies ist nicht unbedingt erforderlich, stellt jedoch sicher, dass die gesuchte Zeichenfolge nicht in eine andere Zeichenfolge eingebettet ist. Dies bedeutet, dass strings sie in einer eigenen Zeile ausgibt.

P.S. Das Makro USPELL setzt die Argumenteinfügungen nicht in Klammern, da es für diesen speziellen Zweck erstellt wurde und nicht zur Wiederverwendung.

0
Kaz