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

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


还是简单地确定系统使用的是哪个处理器,然后确定其Endianess?

评论

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

相关:unix.stackexchange.com/questions/88934/…| askubuntu.com/questions/902907/…| stackoverflow.com/questions/26859098/…

#1 楼

在大字节序系统上(SPARC上的Solaris)

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


0

在小字节序系统上(x86上的Linux)

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


1


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

我需要一个仅外壳(无Perl)的解决方案,该解决方案也可以在AIX / Power和HPUX / Itanium上使用。不幸的是,最后两个表现不佳:AIX报告“ 6”,HPUX空了一行。

使用您的解决方案,我能够设计出在所有这些Unix系统上都可以使用的东西: />
$ echo I | tr -d [:space:] | od -to2 | head -n1 | awk '{print }' | cut -c6

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

我也发现了这一点,它解释了各种平台的字节顺序。某些硬件可以根据操作系统的选择在两种模式下运行:http://labs.hoffmanlabs.com/node/544


如果您要使用awk this该行可以简化为:

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


对于没有“ od”(例如OpenWrt)的小型Linux机器,则尝试“ hexdump”:

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


评论


顺便说一下,那是大写的I(眼睛),而不是小写的l(厄尔)。

–丹尼斯·威廉姆森
2010年7月23日在17:13

(Solaris)->(Solaris,Sparc),尽管Sparc> = V9是双向的。

–克里斯蒂安·丘皮图
2010-09-17 22:13



关心解释它是如何工作的吗?

–马西莫
16年4月1日在11:40

这似乎在Android(Nexus 5)上不起作用。不知道为什么

– wjandrea
17-4-9在17:20



printf“ \ x1” | od -to2 | awk'NR == 1 {print $ 2 == 1}'

–卡兹
17年5月25日在23:24



#2 楼

如果您使用的是较新的Linux计算机(2012年之后的大多数设备),则lscpu现在包含以下信息:

$ lscpu | grep Endian
Byte Order:            Little Endian


此信息已添加到版本2.19的lscpu中,在Fedora> = 17,CentOS> = 6.0,Ubuntu> = 12.04中找到。

请注意,我在Unix.SE上的出色答案中找到了此答案。该答案有很多相关信息,这篇文章只是它的摘要。

#3 楼

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

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

0表示大字节序,而1表示小字节序

或只是更改sys.exitprint可打印输出

评论


这在运行Python 2.4.x的RHEL 5.x / CentOS 5.x系统上不起作用。解决方法:python -c“ import sys; sys.exit(int(sys.byteorder!='big'))”

– JPaget
2014年6月14日23:55



#4 楼

您可以利用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为大尾数。

如果您的包装盒上没有xxd(并且没有busybox),请尝试以下操作:

hexdump -s 5 -n 1 -C /bin/busybox

评论


我认为您的意思是任意ELF ...因为还有其他可执行文件类型,包括shell脚本,perl,python等。不是说您错了,而是-值得记住的是还有其他可执行文件类型(还有出于兴趣,代码位于文本段中,因此旧文本文件忙错误)。

–Pryftan
18年2月11日,0:30

@Pryftan感谢您指出这一点。更正了!

–通州
18年2月11日在20:36

@通州欢迎;很高兴有帮助!

–Pryftan
18年2月12日在14:39

太棒了!适用于基于busybox的嵌入式OS的第一种方法。

– ogurets
18年10月10日在12:37

hexdump版本很棒。它在busybox系统上运行良好。

–domenukk
20-2-7在22:09

#5 楼

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

在Big Endian系统(Solaris,SPARC)上

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


在Little Endian系统上(Linux,Intel)

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


较新的Linux内核

从util-linux软件包2.19版开始,命令lscpu开始包含一个字段与字节序有关。因此,现在您可以简单地使用以下命令找出答案:

$ 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


参考文献


在Linux中是否有系统命令可以报告字节序?


#6 楼

这个Python脚本应该可以为您工作:

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


评论


一种衬里:python -c“从结构导入包;导入sys; sys.exit(int(pack('@ h',1)== pack('
–克里斯蒂安·丘皮图
2010-09-17 20:51

#7 楼

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


它将打印系统的字节序。

#8 楼

我在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


#9 楼

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

评论


编辑:-n 1,抱歉;)

–fae
16年4月1日在11:44

这是与先前答案完全相同的方法,该答案还提供了比您更多的详细信息。

–卡巴斯德
16年4月1日在12:31

#10 楼

要求略有不同:我需要在程序构建配置脚本中进行类似的测试,以确定编译目标计算机是位字节序还是低位字节序,而无需执行代码。该脚本必须将#define HAVE_LITTLE_ENDIAN 1存放到config.h标头中,否则存放在#define HAVE_LITTLE_ENDIAN 0中。

编译目标计算机可能与构建计算机不同,因为我们可能是交叉编译的,这也解释了为什么测试不能进行的原因。尝试运行任何已编译的代码。不可能有一个带有printf语句的C程序来吐出答案。

可能的解决方案是这个。我们生成一个名为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,则为big-endian。如果两个字符串都没有出现,或者甚至都没有出现,那么测试就失败了。

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

两个零保护字确保字符串被隔离。这不是严格必要的,但可以确保我们要查找的字符串未嵌入其他字符串中,这意味着strings会自行将其输出在一行上。

P.S. USPELL宏不会括入参数插入,因为它是为特定目的而不是重复使用而设计的。

评论


并非所有项目都必须这样做,但是autoconf / automake是否没有此检查?我的项目总是足够小,可以在其中创建自己的Makefile(尽管并不总是基本的),所以我除了在必要时进行一些修改和常规界面之外,对其他工具一无所知。但是我确实想知道它们是否具有检测功能。也许即使您不需要它,也只是以为我会排除这种可能性。

–Pryftan
18年2月11日,0:34