40

Does anyone know of a command that reports whether a system is Big Endian or Little Endian, or is the best option a technique like this using Perl or a string of commands?

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

References

slm
  • 369,824
  • What's wrong with the od method? It's simple and works everywhere. It's what I thought of before reading the body of your question. – Gilles 'SO- stop being evil' Aug 31 '13 at 10:57
  • @Gilles - nothing really, feels a little like a hack (at least to me). True it would appear to be portable on other systems such as Solaris + AIX, but it seemed like a system's Endianness should be a little more explicitly determined like 32-bit vs. 64-bit, so I was a little surprised that it wasn't. The newer lscpu method is more what I would come to expect. – slm Aug 31 '13 at 12:11
  • Endianness is in practice easier to determine than word size, because you'll have a hard time finding platforms that aren't either little-endian or big-endian (at least for integers, floats are another matter) whereas there are plenty of mixes between 32-bit and 64-bit (CPU, kernel, userland, a given process). – Gilles 'SO- stop being evil' Aug 31 '13 at 12:15
  • @Gilles - yes my view of the world is probably slighted since I primarily grew up with either Solaris or Linux. Not so much beyond that. – slm Aug 31 '13 at 12:26
  • the od approach should work on most open systems, not only linux, which would be the case with using lscpu. So what is "best" depends on the circumstances. – MattBianco Aug 08 '14 at 11:06
  • I guess the command lscpu does not work on RHEL 5.7? I installed the followin rpm and nothing, any ideas? [root@test]# rpm -qa | grep -i util-linux util-linux-2.13-0.59.el5_8 –  Aug 25 '14 at 12:59
  • @user81936 - yes the pacakage util-linux-ng was a fork of util-linux, they've since merged back into util-linux. I cover the lack of this package in any of the EL5 repos here: http://unix.stackexchange.com/questions/84357/how-to-install-lsblk-on-centos-5. As I stated in my A lscpu just isn't available on CentOS 5. Not until util-linux ver. 2.19 did lscpu even support the endianness. You'll hae to use an alternative method on that OS. – slm Aug 27 '14 at 01:31
  • Can somebody please explain why exactly the "od | awk" command produces this output? After disseminating the output of the single steps and researching the topic for more than one hour I am still left puzzled because it just seems so counterintuitive. On a little endian machine echo -n | od -to2 | awk 'FNR==1{ print $2} returns 000111, so the least significant element is right, right? And aren't character streams typically processed from left to right on screen? So how doesn't that indicate that the least significant element is processed last, equivalent to big rather than small endian? – Sam Apr 10 '18 at 17:34
  • @Sam - it has to do with the ascii value for the letter I. The letter I maps to DEC 73 which is OCT 111. When we echo this on big vs. little endian systems using od -to2 we either get 000111 or 111000. - https://rogerhub.com/~r/code.rogerhub/terminal-fu/112/how-to-tell-if-your-system-is-big-endian-or-little-endian/. – slm Apr 11 '18 at 03:29
  • @slm Hmm... my question regarded the od part more than anyhing else, but after yet some more experimentation and contemplation I think I have it figured out. I think I made the mistake of assuming that the -to2 flag with a 1 byte input makes od apply a "padding" sort of byte, but I understand now that it simply reads past EOF, parsing a zero byte from the terminal driver. Then it makes sense that that byte is interpreted as the more significant one in little endian and the less significant in big endian, thus being placed left or right, respectively. Please correct me if I'm wrong. – Sam Apr 11 '18 at 08:14
  • Related: https://serverfault.com/questions/163487/how-to-tell-if-a-linux-system-is-big-endian-or-little-endian – Ciro Santilli OurBigBook.com Mar 24 '20 at 18:28

5 Answers5

49

lscpu

The lscpu command shows (among other things):

Byte Order:            Little Endian

Systems this is known to work on

  • CentOS 6
  • Ubuntu (12.04, 12.10, 13.04, 13.10, 14.04)
  • Fedora (17,18,19)
  • ArchLinux 2012+
  • Linux Mint Debian (therefore assuming Debian testing as well).

Systems this is known to not work on

  • Fedora 14
  • CentOS 5 (assuming RHEL5 because of this)

Why the apparent differences across distros?

After much digging I found out why. It looks like version util-linux version 2.19 was the first version that included the feature where lscpu shows you the output reporting your system's Endianness.

As a test I compiled both version 2.18 and 2.19 on my Fedora 14 system and the output below shows the differences:

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

The above versions were downloaded from the kernel.org website.

dotancohen
  • 15,864
10

Using python:

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

or:

printf '\1' | od -dAn
1

where 1 is for little endian and 00256 for big endian.

Or using a shorter perl version:

$ perl -V:byteorder
byteorder='12345678';
cuonglm
  • 153,898
7

One method I found on Debian/Ubuntu systems is to run this command:

$ 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

This will show you the words little or big depending on the architecture your system is comprised of:

$ dpkg-architecture | grep -i end
DEB_BUILD_ARCH_ENDIAN=little
DEB_HOST_ARCH_ENDIAN=little
slm
  • 369,824
5

A POSIX Shell & C solution:

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
  • Or skip creating a binary altogether and just run the preprocessing step: gcc -E -dM - <<< '#include <endian.h>' | grep BYTE_ORDER (this preprocesses just the single line #include of C source on stdin, and dumps all the defines that were computed). This is friendlier for gcc cross-builds when build-time checks would trip you up. – mr.spuratic Nov 09 '23 at 12:05
2

If you are on a system that does not have 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;
}
chicks
  • 1,112