Gibt es unter Linux einen Systembefehl, der die Endianness meldet?

30

Kennt jemand einen Befehl, der meldet, ob es sich bei einem System um Big Endian oder Little Endian handelt, oder ist die beste Option eine Technik wie diese, die Perl oder eine Folge von Befehlen verwendet?

Perl

# little
$ perl -MConfig -e 'print "$Config{byteorder}\n";'
12345678

# big
$ perl -MConfig -e 'print "$Config{byteorder}\n";'
87654321

od | awk

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

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

Verweise

slm
quelle
Was ist los mit der odMethode? Es ist einfach und funktioniert überall. Ich habe darüber nachgedacht, bevor ich Ihre Frage gelesen habe.
Gilles 'SO - hör auf böse zu sein'
@ Gilles - nichts wirklich, fühlt sich ein bisschen an wie ein Hack (zumindest für mich). Es stimmt, dass es auf anderen Systemen wie Solaris + AIX portabel zu sein scheint, aber es schien, dass die Endianness eines Systems ein bisschen expliziter sein sollte, wie 32-Bit vs. 64-Bit. t. Die neuere lscpuMethode ist mehr, als ich erwarten würde.
slm
Endianness ist in der Praxis einfacher zu bestimmen als die Wortgröße, da es schwierig ist, Plattformen zu finden, die weder Little-Endian noch Big-Endian sind (zumindest für Ganzzahlen sind Floats eine andere Sache), während es viele Mischungen gibt zwischen 32-Bit und 64-Bit (CPU, Kernel, Userland, ein bestimmter Prozess).
Gilles 'SO- hör auf böse zu sein'
@Gilles - ja, meine Sicht auf die Welt ist wahrscheinlich eingeschränkt, da ich hauptsächlich mit Solaris oder Linux aufgewachsen bin. Nicht so sehr darüber hinaus.
slm
Der odAnsatz sollte auf den meisten offenen Systemen funktionieren, nicht nur auf Linux, was bei der Verwendung der Fall wäre lscpu. Was also "am besten" ist, hängt von den Umständen ab.
MattBianco

Antworten:

40

lscpu

Der lscpuBefehl zeigt (unter anderem):

Byte Order:            Little Endian

Systeme, auf denen dies bekanntermaßen funktioniert

  • CentOS 6
  • Ubuntu (12.04, 12.10, 13.04, 13.10, 14.04)
  • Fedora (17,18,19)
  • ArchLinux 2012+
  • Linux Mint Debian (setzt daher auch Debian-Tests voraus).

Systeme, auf denen dies bekanntermaßen nicht funktioniert

  • Fedora 14
  • CentOS 5 (davon ausgehend RHEL5)

Warum die offensichtlichen Unterschiede zwischen den Distributionen?

Nach langem Graben fand ich heraus warum. Es sieht so aus, als ob die Version util-linux 2.19 die erste Version war, die die Funktion enthielt, mit der lscpuSie die Ausgabe sehen können, die die Endianität Ihres Systems meldet.

Als Test habe ich beide Versionen 2.18 und 2.19 auf meinem Fedora 14-System kompiliert und die folgende Ausgabe zeigt die Unterschiede:

util-linux 2.18

$ util-linux-ng-2.18/sys-utils/lscpu 
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
CPU(s):                4
Thread(s) per core:    2
Core(s) per socket:    2
CPU socket(s):         1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 37
Stepping:              5
CPU MHz:               1199.000
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              3072K
NUMA node0 CPU(s):     0-3

util-linux 2.19

$ util-linux-2.19/sys-utils/lscpu 
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    2
Core(s) per socket:    2
CPU socket(s):         1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 37
Stepping:              5
CPU MHz:               2667.000
BogoMIPS:              5320.02
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              3072K
NUMA node0 CPU(s):     0-3

Die obigen Versionen wurden von der kernel.org-Website heruntergeladen .

David Baggerman
quelle
Danke David, das habe ich verpasst, als ich diese Datei gelesen habe. Muss blind werden 8-)
slm
Ich verstehe, warum ich es verpasst habe. Auf meinem Fedora 14-System lscpuwird dieser Wert nicht angezeigt, auf meinem Ubuntu 12.10-System jedoch. Wenn es Ihnen nichts ausmacht, kann ich Ihre Antwort in Abschnitte für die verschiedenen Systeme und Vorgehensweisen aufteilen.
slm
@ slm Sicher, mach weiter. Als Referenz lscpufunktioniert auch auf Archlinux.
David Baggerman
Welche Version von Arch?
slm
Arch hat keine Versionen; Es ist eine rollende Veröffentlichung ...
Jasonwryan
6

Eine Methode, die ich auf Debian / Ubuntu-Systemen gefunden habe, ist, diesen Befehl auszuführen:

$ dpkg-architecture
DEB_BUILD_ARCH=amd64
DEB_BUILD_ARCH_BITS=64
DEB_BUILD_ARCH_CPU=amd64
DEB_BUILD_ARCH_ENDIAN=little
DEB_BUILD_ARCH_OS=linux
DEB_BUILD_GNU_CPU=x86_64
DEB_BUILD_GNU_SYSTEM=linux-gnu
DEB_BUILD_GNU_TYPE=x86_64-linux-gnu
DEB_BUILD_MULTIARCH=x86_64-linux-gnu
DEB_HOST_ARCH=amd64
DEB_HOST_ARCH_BITS=64
DEB_HOST_ARCH_CPU=amd64
DEB_HOST_ARCH_ENDIAN=little
DEB_HOST_ARCH_OS=linux
DEB_HOST_GNU_CPU=x86_64
DEB_HOST_GNU_SYSTEM=linux-gnu
DEB_HOST_GNU_TYPE=x86_64-linux-gnu
DEB_HOST_MULTIARCH=x86_64-linux-gnu

Dies zeigt Ihnen die Wörter "klein" oder "groß", abhängig von der Architektur, aus der Ihr System besteht:

$ dpkg-architecture | grep -i end
DEB_BUILD_ARCH_ENDIAN=little
DEB_HOST_ARCH_ENDIAN=little
slm
quelle
6

Verwenden von python:

$ python -c "import sys;print sys.byteorder"
little

oder:

printf '\1' | od -dAn
1

Wo 1ist für Little Endian und 00256für Big Endian.

Oder mit einer kürzeren perlVersion:

$ perl -V:byteorder
byteorder='12345678';
cuonglm
quelle
5

Eine POSIX Shell & C-Lösung:

cat << EOF > foo.c

#include <endian.h>
#include <stdio.h>

int main() {
  printf("Byte Order: ");
  if (BYTE_ORDER == LITTLE_ENDIAN) 
    printf("little");
  else {
    if (BYTE_ORDER == BIG_ENDIAN)
      printf("big");
    else
      printf("unknown");
  }
  printf(" endian.\n");
  return 0;
}
EOF

gcc -D__USE_POSIX foo.c
./a.out

quelle
1

Wenn Sie sich auf einem System befinden, das nicht über Folgendes verfügt endian.h:

#include <stdio.h>

int main() {
  int test = 0;
  char *bytes = (char *) &test;
  *bytes = 0x1;

  printf("Byte Order: ");
  if (test == 1){
    printf("little");
  }
  else {
      printf("big");
  }
  printf(" endian.\n");
  return 0;
}
Matthew V Carey
quelle
Was keine Liebe für VAX Middle-Endian?
am
Gut gesehen, ich war so in meine aktuellen Intel-> PowerPC-Probleme vertieft, dass ich mir nichts so Schreckliches vorgestellt hatte.
Matthew V Carey