Answers:
在大字节序系统上(SPARC上的Solaris)
$ echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6
0
在小端系统上(Linux在x86上)
$ 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 $2}' | cut -c6
关于某人发布的Python解决方案,它在Jython中不起作用,因为JVM将所有内容都视为Big。如果有人可以在Jython工作,请发布!
另外,我发现了这一点,这解释了各种平台的字节顺序。根据操作系统选择的内容,某些硬件可以在任何一种模式下运行: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}'
I
(眼睛),而不是小写字母l
(ell)。
printf "\x1" | od -to2 | awk 'NR==1{print$2==1}'
如果您使用的是较新的Linux机器(2012年之后的大多数机器),则lscpu
现在包含以下信息:
$ lscpu | grep Endian
Byte Order: Little Endian
它已添加到lscpu
2.19版本中,该版本位于Fedora> = 17,CentOS> = 6.0,Ubuntu> = 12.04中。
请注意,我在Unix.SE上的出色答案中找到了这个答案。该答案有很多相关信息,本文仅是其摘要。
主要答案可以使用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
从util-linux软件包的2.19版本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
这个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 "from struct import pack;import sys;sys.exit(int(pack('@h',1)==pack('<h',1)))"
。退出代码对于大字节序为0,对于小字节序为1。
您可以利用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格式的单行命令:
hexdump -s 5 -n 1 /bin/sh
要求略有不同:我需要在程序构建配置脚本中进行类似的测试,以确定编译目标计算机是位字节序还是低位字节序,而无需执行代码。脚本必须存放#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
将其单独输出到一行中。
PS USPELL
宏不会括号内的参数插入,因为它是为特定目的而不是重复使用而设计的。