题 如何判断Linux系统是大端还是小端?


我知道某些处理器是Big Endian而其他处理器是Little Endian。但是有命令,bash脚本,python脚本或一系列命令可以在命令行使用来确定系统是Big Endian还是Little Endian?就像是:

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

或者更简单地确定系统正在使用哪个处理器并使用它来确定其Endianess?


82
2017-07-23 16:58




这是使用perl的解决方案: stackoverflow.com/questions/2610849/... - slu


答案:


在Big Endian系统上(SPARC上的Solaris)

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

0

在一个小端系统上(Linux on x86)

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

1


上面的解决方案很聪明,适用于Linux * 86和Solaris Sparc。

我需要一个仅支持shell(无Perl)的解决方案,它也适用于AIX / Power和HPUX / Itanium。不幸的是,最后两个不好玩:AIX报告“6”,HPUX给出一个空行。

使用您的解决方案,我能够制作适用于所有这些Unix系统的东西:

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

关于某人发布的Python解决方案,它在Jython中不起作用,因为JVM将所有内容都视为Big。如果有人可以让它在Jython中工作,请发布!

此外,我发现了这个,它解释了各种平台的字节顺序。某些硬件可以在任一模式下运行,具体取决于O / S选择的内容: http://labs.hoffmanlabs.com/node/544


如果你打算使用awk,这行可以简化为:

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

对于没有'od'的小型Linux机箱(比如OpenWrt),请尝试'hexdump':

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

102
2017-07-23 17:04



这是一个大写 I (眼睛)而不是小写 l (顺便说一下)。 - Dennis Williamson
(Solaris) - >(Solaris,Sparc),虽然Sparc> = V9是bi endian。 - Cristian Ciupitu
注意解释它是如何工作的? - Massimo
这似乎不适用于Android(Nexus 5)。不知道为什么...... - wjandrea
printf "\x1" | od -to2 | awk 'NR==1{print$2==1}' - Kaz


这是一个更优雅的python单行脚本

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

退出代码 0 意味着大端和 1 意思是小端

或者只是改变 sys.exit 至 print 用于可打印输出


29
2018-05-21 20:26



这不适用于运行Python 2.4.x的RHEL 5.x / CentOS 5.x系统。这是一个修复: python -c "import sys;sys.exit(int(sys.byteorder!='big'))" - JPaget


如果你在一台相当新的Linux机器上 (2012年以后的大部分内容) 然后 lscpu 现在包含以下信息:

$ lscpu | grep Endian
Byte Order:            Little Endian

这被添加到 lscpu 在版本2.19中,在Fedora> = 17,CentOS> = 6.0,Ubuntu> = 12.04中找到。

请注意,我发现了这个答案 关于Unix.SE的这个很棒的答案。这个答案有很多相关信息,这篇文章只是对它的总结。


26
2018-06-15 11:26





主要答案可以略微简化使用 awk

在Big Endian系统上(Solaris,SPARC)

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

在Little Endian系统上(Linux,Intel)

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

较新的Linux内核

截至2.19版本的util-linux包命令 lscpu 开始包括与Endianness相关的字段。所以现在你可以简单地使用这个命令找到它:

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

这已经在Ubuntu 12.10和CentOS 6上得到了证实。所以我愿意假设大多数3.0+ Linux内核现在提供这个。

在Debian / Ubuntu系统上,您也可以使用此命令,不确定它何时可用:

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

参考


10
2017-08-30 23:41





这个Python脚本应该适合你:

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

9
2017-07-23 17:28



一个班轮: python -c "from struct import pack;import sys;sys.exit(int(pack('@h',1)==pack('<h',1)))"。对于大端,退出代码为0,对于小端,退出代码为1。 - Cristian Ciupitu
哈!很简约!多谢你们! - Viet


python -c "import sys; print(sys.byteorder)"

它将打印系统的endianess。


6
2018-05-28 07:17





我在Jython中找到了一种方法。由于Jython(JVM上的Python)在VM上运行,因此无论硬件如何,它都会报告大端。

此解决方案适用于Linux,Solaris,AIX和HPUX。尚未在Windows上测试过:

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

3
2017-11-30 22:40





您可以利用ELF文件格式来确定系统的字节顺序。例如,以十六进制打印任意ELF文件的前六个字节:

xxd -c 1 -l 6 /bin/ls

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

如果最后一行(六字节)是01,则根据 ELF格式,01是小端,02是大端。


3
2018-01-15 18:23



这是 究竟 我需要什么。谢谢! - Vasily G
我认为你的意思是一个任意的ELF ......因为还有其他可执行类型,包括shell脚本,perl,python等。不过你说错了 - 只是说它值得记住还有其他可执行类型(和为了感兴趣,代码在文本段中,因此旧文本文件繁忙错误)。 - Pryftan
@Pryftan感谢你指出这一点。纠正了! - Tong Zhou
@TongZhou欢迎;很高兴有帮助! - Pryftan


基于ELF格式的单行命令:
hexdump -s 5 -n 1 /bin/sh


0
2018-04-01 11:36



编辑:-n 1,对不起;) - fae
这与a完全相同 以前的答案,这也提供了比你更多的细节。 - kasperd


稍微不同的要求:我需要在程序构建配置脚本中进行这样的测试,以确定是否 编译目标机器 有点或小端, 不执行代码。脚本必须存款 #define HAVE_LITTLE_ENDIAN 1 变成一个 config.h 标题,否则 #define HAVE_LITTLE_ENDIAN 0

编译目标机器可能与构建机器不同,因为我们可能是交叉编译,这也解释了为什么测试不能尝试运行任何编译代码。有一个小C程序是不可能的 printf 吐出答案的陈述。

可能的解决方案就是这样。我们生成一个名为的文件 conftest.c 其中包含:

#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                                                                          
};

现在,我们将其编译为 conftest.o 使用:

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

然后我们运行:

$ strings conftest.o
PSILXINUEROCMIWD

如果是字符串 PSILXINUEROCMIWD 发生时,目标是小端。如果是字符串 LISPUNIXCOREDWIM 发生了,它是大端的。如果两个字符串都没有出现,或者更令人惊讶地发生,那么测试就失败了。

这种方法有效,因为程序中计算的“fourcc”常量具有与机器无关的值,表示相同的整数而不管字节顺序。它们在目标文件中的存储表示遵循目标系统的字节顺序,并且可以通过基于字符的视图查看 strings

两个零保护字确保字符串被隔离。这不是绝对必要的,但它确保我们正在寻找的字符串不会嵌入到其他字符串中,这意味着 strings 将自己输出一行。

附:该 USPELL 宏没有对参数插入进行括号化,因为它是为了这个特定目的而制作的,而不是为了重复使用。


0
2018-05-26 00:37



并非所有项目都需要,但autoconf / automake没有这个检查吗?我的项目总是足够小,我可以制作自己的Makefile(虽然不总是基本的)所以除了在必要时进行一些修改和一般界面之外,我真的不知道那些工具。但我不知道他们是否有检测。也许你不需要它,即使它确实如此,只是想我会把可能性抛出去。 - Pryftan