Czy w Linuksie jest polecenie systemowe, które zgłasza endianizm?

30

Czy ktoś wie o poleceniu, które informuje, czy system to Big Endian, czy Little Endian, czy też najlepszą opcją jest technika taka jak Perl lub ciąg poleceń?

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

Referencje

slm
źródło
Co jest nie tak z tą odmetodą? To proste i działa wszędzie. Właśnie o tym myślałem przed przeczytaniem treści twojego pytania.
Gilles 'SO - przestań być zły'
@Gilles - nic tak naprawdę nie wygląda trochę jak hack (przynajmniej dla mnie). To prawda, że ​​wydaje się być przenośny na innych systemach, takich jak Solaris + AIX, ale wydawało się, że Endianness systemu powinien być nieco bardziej wyraźnie określony, jak 32-bitowy vs. 64-bitowy, więc byłem trochę zaskoczony, że nie był t. Nowsza lscpumetoda jest tym, czego mógłbym się spodziewać.
slm
Endianness jest w praktyce łatwiejszy do określenia niż rozmiar słowa, ponieważ trudno będzie znaleźć platformy, które nie są ani little-endian, ani big-endian (przynajmniej dla liczb całkowitych, zmiennoprzecinkowe to inna sprawa), podczas gdy istnieje wiele miksów od 32-bitowego do 64-bitowego (procesor, jądro, obszar użytkownika, dany proces).
Gilles 'SO - przestań być zły'
@Gilles - tak, mój pogląd na świat jest prawdopodobnie niewielki, ponieważ dorastałem głównie w systemie Solaris lub Linux. Nie więcej niż to.
slm
takie odpodejście powinno działać na większości otwartych systemów, nie tylko na Linuksie, jak w przypadku używania lscpu. To, co jest „najlepsze”, zależy od okoliczności.
MattBianco,

Odpowiedzi:

40

lscpu

Te lscpupokazy Command (między innymi):

Byte Order:            Little Endian

Systemy, o których wiadomo, że działają

  • CentOS 6
  • Ubuntu (12.04, 12.10, 13.04, 13.10, 14.04)
  • Fedora (17,18,19)
  • ArchLinux 2012+
  • Linux Mint Debian (tym samym zakładając również testy Debiana).

Systemy, o których wiadomo, że nie działają

  • Fedora 14
  • CentOS 5 (przy założeniu RHEL5 z tego powodu)

Dlaczego pozorne różnice między dystrybucjami?

Po wielu kopaniach dowiedziałem się, dlaczego. Wygląda na to, że wersja util-linux wersja 2.19 była pierwszą wersją, która zawierała funkcję, w której lscpuwyświetla dane wyjściowe raportujące Endianness systemu.

Jako test skompilowałem zarówno wersję 2.18, jak i 2.19 na moim systemie Fedora 14, a wynik poniżej pokazuje różnice:

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

Powyższe wersje zostały pobrane ze strony kernel.org .

David Baggerman
źródło
Dzięki David, przegapiłem to, kiedy przeglądałem ten plik. Musi być ślepy 8-)
slm
Rozumiem, dlaczego mi tego brakowało. Mój system Fedora 14 lscpunie wyświetla tej wartości, jednak robi to mój system Ubuntu 12.10. Jeśli nie masz nic przeciwko, mogę wziąć twoją odpowiedź i podzielić ją na sekcje dla różnych systemów i sposobów na zrobienie tego na każdym z nich.
slm
@slm Pewnie, śmiało. W lscpucelach informacyjnych działa również na Archlinux.
David Baggerman
Która wersja Arch?
slm
Arch nie ma wersji; jest to wersja krocząca ...
jasonwryan
6

Jedną metodą znalezioną w systemach Debian / Ubuntu jest uruchomienie tego polecenia:

$ 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

To pokaże słowa małe lub duże w zależności od architektury, z której składa się twój system:

$ dpkg-architecture | grep -i end
DEB_BUILD_ARCH_ENDIAN=little
DEB_HOST_ARCH_ENDIAN=little
slm
źródło
6

Używanie python:

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

lub:

printf '\1' | od -dAn
1

gdzie 1jest dla małego endiana i 00256dla dużego endiana.

Lub używając krótszej perlwersji:

$ perl -V:byteorder
byteorder='12345678';
Cuonglm
źródło
5

Rozwiązanie 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

źródło
1

Jeśli korzystasz z systemu, który nie ma 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
źródło
Co nie ma miłości do VAX mid-endian?
thrig
Dobrze zauważony, byłem tak pochłonięty moimi obecnymi problemami z Intel-> PowerPC, że nie wymyśliłem czegoś tak okropnego.
Matthew V Carey