Existe-t-il une commande système, sous Linux, qui signale l'endianité?

31

Quelqu'un connaît-il une commande qui signale si un système est Big Endian ou Little Endian, ou est-ce que la meilleure option est une technique comme celle-ci utilisant Perl ou une chaîne de commandes?

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

Les références

slm
la source
Quel est le problème avec la odméthode? C'est simple et fonctionne partout. C'est ce à quoi j'ai pensé avant de lire le corps de votre question.
Gilles 'SO- arrête d'être méchant'
@ Gilles - rien de vraiment, ressemble un peu à un hack (du moins pour moi). Il est vrai qu'il semble portable sur d'autres systèmes tels que Solaris + AIX, mais il semble que l'endianité d'un système devrait être un peu plus explicitement déterminée comme 32 bits contre 64 bits, donc j'ai été un peu surpris que ce ne soit pas le cas. t. La nouvelle lscpuméthode est plus ce à quoi je m'attendrais.
slm
L'endianité est en pratique plus facile à déterminer que la taille des mots, car vous aurez du mal à trouver des plates-formes qui ne sont ni petit-boutian ni big-endian (au moins pour les entiers, les flottants sont une autre affaire) alors qu'il existe de nombreux mélanges entre 32 bits et 64 bits (CPU, noyau, espace utilisateur, un processus donné).
Gilles 'SO- arrête d'être méchant'
@Gilles - oui, ma vision du monde est probablement altérée car j'ai principalement grandi avec Solaris ou Linux. Pas tant que ça.
slm
l' odapproche devrait fonctionner sur la plupart des systèmes ouverts, pas seulement sur linux, ce qui serait le cas avec l'utilisation lscpu. Donc, ce qui est "meilleur" dépend des circonstances.
MattBianco

Réponses:

41

lscpu

La lscpucommande affiche (entre autres):

Byte Order:            Little Endian

Systèmes sur lesquels on sait qu'ils fonctionnent

  • CentOS 6
  • Ubuntu (12.04, 12.10, 13.04, 13.10, 14.04)
  • Fedora (17,18,19)
  • ArchLinux 2012+
  • Linux Mint Debian (en supposant donc également les tests Debian).

Systèmes connus pour ne pas fonctionner

  • Fedora 14
  • CentOS 5 (en supposant RHEL5 à cause de cela)

Pourquoi les différences apparentes entre les distributions?

Après beaucoup de fouilles, j'ai découvert pourquoi. Il semble que la version util-linux version 2.19 soit la première version à inclure la fonctionnalité qui lscpuvous montre la sortie signalant l'endianité de votre système.

Comme test, j'ai compilé les versions 2.18 et 2.19 sur mon système Fedora 14 et la sortie ci-dessous montre les différences:

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

Les versions ci-dessus ont été téléchargées à partir du site Web kernel.org .

David Baggerman
la source
Merci David, ça m'a manqué quand je criais ce fichier. Doit devenir aveugle 8-)
slm
Je vois pourquoi je l'ai raté. Mon système Fedora 14 lscpun'affiche pas cette valeur, contrairement à mon système Ubuntu 12.10. Si cela ne vous dérange pas, je pourrais prendre votre réponse et la diviser en sections pour les différents systèmes et les façons de le faire sur chacun.
slm
@slm Bien sûr, allez-y. Pour référence, lscpufonctionne également sur Archlinux.
David Baggerman
Quelle version d'Arch?
slm
Arch n'a pas de versions; c'est une version qui roule ...
jasonwryan
7

En utilisant python:

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

ou:

printf '\1' | od -dAn
1

1est pour petit endian et 00256pour big endian.

Ou en utilisant une perlversion plus courte :

$ perl -V:byteorder
byteorder='12345678';
cuonglm
la source
6

Une méthode que j'ai trouvée sur les systèmes Debian / Ubuntu consiste à exécuter cette commande:

$ 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

Cela vous montrera les mots petits ou grands selon l'architecture de votre système est composé de:

$ dpkg-architecture | grep -i end
DEB_BUILD_ARCH_ENDIAN=little
DEB_HOST_ARCH_ENDIAN=little
slm
la source
5

Une solution POSIX Shell & C:

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

la source
1

Si vous êtes sur un système qui n'a pas 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
la source
Quel amour pour VAX middle-endian?
thrig
Bien repéré, j'étais tellement absorbé par mes problèmes Intel-> PowerPC actuels, je n'avais pas conçu quelque chose d'aussi horrible.
Matthew V Carey