Linuxシステムがビッグエンディアンかリトルエンディアンかを確認するにはどうすればよいですか?


91

特定のプロセッサがビッグエンディアンであり、他のプロセッサがリトルエンディアンであることを知っています。しかし、システムがビッグエンディアンかリトルエンディアンかを判断するためにコマンドラインで使用できるコマンド、bashスクリプト、pythonスクリプト、または一連のコマンドはありますか?何かのようなもの:

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

または、システムが使用しているプロセッサを特定し、それを使用してエンディアネスを特定する方が簡単ですか?


perlを使用したソリューションは次のとおりです。stackoverflow.com
questions / 2610849

回答:


110

ビッグエンディアンシステム(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に最適です。

AIX / PowerおよびHPUX / Itaniumでも動作するシェルのみ(Perlなし)のソリューションが必要でした。残念ながら、最後の2つはうまく再生されません。AIXは「6」を報告し、HPUXは空の行を提供します。

あなたのソリューションを使用して、私はこれらすべてのUnixシステムで動作するものを作成することができました。

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

誰かが投稿したPythonソリューションに関しては、JVMはすべてをBigとして扱うため、Jythonでは機能しません。誰でもJythonで動作するようになったら、投稿してください!

また、さまざまなプラットフォームのエンディアンを説明するこれを見つけました。一部のハードウェアは、O / Sの選択内容に応じて、どちらのモードでも動作できます。http//labs.hoffmanlabs.com/node/544


awkを使用する場合、この行は次のように簡略化できます。

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

「od」(OpenWrtなど)のない小さなLinuxボックスの場合、「hexdump」を試してください。

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

2
ちなみに、これはI小文字l(エル)ではなく、大文字(目)です。
デニスウィリアムソン

1
(Solaris)->(Solaris、Sparc)、ただしSparc> = V9はバイエンディアンです。
クリスチャン・シウピトゥ

1
それがどのように機能するかを説明する気ですか?
マッシモ

これはAndroid(Nexus 5)では機能しないようです。なぜわからない
...-wjandrea

printf "\x1" | od -to2 | awk 'NR==1{print$2==1}'
カズ

35

かなり最近のLinuxマシン(2012年以降のほとんどのもの)を使用しlscpuている場合、次の情報が含まれています。

$ lscpu | grep Endian
Byte Order:            Little Endian

これはlscpu、Fedora> = 17、CentOS> = 6.0、Ubuntu> = 12.04にあるバージョン2.19 に追加されました。

Unix.SEでのこの素晴らしい回答からこの回答を見つけたことに注意してください。その答えには多くの関連情報がありますが、この投稿はその概要です。


31

これは、よりエレガントなpythonの1行スクリプトです。

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

終了コード0はビッグエンディアンとリトルエンディアンを1意味します

または単に印刷可能な出力に変更sys.exitprintます


4
これは、Python 2.4.xを実行しているRHEL 5.x / CentOS 5.xシステムでは機能しません。ここで修正があります:python -c "import sys;sys.exit(int(sys.byteorder!='big'))"
JPaget

10

主な答えは、以下を使用してわずかに簡略化できますawk

ビッグエンディアンシステム(Solaris、SPARC)

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

リトルエンディアンシステム(Linux、Intel)

$ echo -n I | od -to2 | awk 'FNR==1{ print substr($2,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

参照資料


9

このPythonスクリプトは次のように機能します。

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

4
1つのライナー:python -c "from struct import pack;import sys;sys.exit(int(pack('@h',1)==pack('<h',1)))"。終了コードは、ビッグエンディアンの場合は0、リトルエンディアンの場合は1です。
クリスチャンシウピトゥ


6

ELFファイル形式を利用して、システムのエンディアンを判断できます。たとえば、任意のELFファイルの最初の6バイトを16進数で出力します。

xxd -c 1 -l 6 /bin/ls

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

ELF形式によれば、最後の行(6バイト)が01の場合、01はリトルエンディアン、02はビッグエンディアンです。

あなたがxxd箱を持っていない(そしてbusyboxを持っている)場合、これを試してください:

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


私はあなたが任意のELFを意味すると思います...シェルスクリプト、perl、pythonなどを含む他の実行可能型があるので、そうでなければあなたが間違っていると言っていない-他の実行可能型があることを覚えておく価値があるとだけ言って興味深いことに、コードはテキストセグメントにあるため、古いテキストファイルのビジーエラーです。
プリフタン

1
@Pryftan指摘してくれてありがとう。それを修正しました!
トン周

@TongZhouようこそ; 助けてくれてうれしい!
プリフタン

驚くばかり!busyboxベースの組み込みOSで動作する最初の方法。
オグレッツ

3

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

2

ELF形式に基づく単一行コマンド:
hexdump -s 5 -n 1 /bin/sh


編集:-n 1、ごめん;)
fae

1
これは前の回答とまったく同じ方法で、あなたよりも多くの詳細を提供しました。
カスペルド

0

わずかに異なる要件:コードを実行せずにコンパイルターゲットマシンがビットエンディアンかリトルエンディアンかを判断するために、プログラムビルド構成スクリプトでこのようなテストが必要です。スクリプトは#define HAVE_LITTLE_ENDIAN 1config.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が発生する場合、それはビッグエンディアンです。どちらの文字列も発生しないか、さらに驚くべきことに、両方が発生する場合、テストは失敗しています。

このアプローチは、プログラムで計算された「fourcc」定数がマシンに依存しない値を持ち、エンディアンに関係なく同じ整数を示すために機能します。オブジェクトファイル内のストレージ表現は、ターゲットシステムのエンディアンに従います。これは、の文字​​ベースのビューを介して表示されstringsます。

2つのゼロガードワードにより、文字列が分離されます。これは厳密に必要というわけではありませんが、探している文字列が他の文字列に埋め込まれていないことを保証します。つまり、stringsそれ自体で行に出力します。

PS USPELLマクロは、再利用ではなく、この特定の目的のために作成されているため、引数の挿入を括弧で囲みません。


すべてのプロジェクトに必要なわけではありませんが、autoconf / automakeにはこのチェックがありませんか?私のプロジェクトは常に自分のMakefileを作成できるほど小さいので(常に基本的ではありませんが)、必要なときにいくつかの変更を加えることと一般的なインターフェイス以外のツールを実際には知りません。たぶん、たとえそれが必要だったとしても、あなたはそれを必要としなかったのかもしれません。
プリフタン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.