web-dev-qa-db-ja.com

Linuxシステムがビッグエンディアンかリトルエンディアンかを確認する方法は?

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

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

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

95
Jake Wilson

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

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

リトルエンディアンシステム(Linux on x86)

$ 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}'
114
krissi

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

$ lscpu | grep Endian
Byte Order:            Little Endian

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

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

40
dotancohen

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

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

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

または単にsys.exitからprintは印刷可能な出力用

32
mchurichi

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

10
Tong Zhou

主な答えは、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

参考文献

10
slm

この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 "import sys; print(sys.byteorder)"

システムのエンディアンを出力します。

7
prembhaskal

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
Foo

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

2
fae

少し異なる要件:コンパイルターゲットマシンがビットかリトルエンディアンかコードを実行しない場合かどうかを判別するために、プログラムビルド構成スクリプトでこのようなテストが必要です。スクリプトは#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はそれ自体を1行に出力します。

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

0
Kaz