特定のプロセッサがビッグエンディアンで、他のプロセッサがリトルエンディアンであることを知っています。しかし、システムがビッグエンディアンかリトルエンディアンかを判断するためにコマンドラインで使用できるコマンド、bashスクリプト、pythonスクリプトまたは一連のコマンドはありますか?
if <some code> then
echo Big Endian
else
echo Little Endian
fi
または、システムが使用しているプロセッサを特定し、それを基にエンディアネスを特定する方が簡単ですか?
ビッグエンディアンシステム(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}'
かなり最近の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でのこの素晴らしい回答 からこの回答を見つけたことに注意してください。その回答には関連情報がたくさんありますが、この投稿はその要約にすぎません。
これはよりエレガントなpython 1行のスクリプトです
python -c "import sys;sys.exit(0 if sys.byteorder=='big' else 1)"
終了コード0
はビッグエンディアンを意味し、1
はリトルエンディアンを意味します
または単にsys.exit
からprint
は印刷可能な出力用
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
主な答えは、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
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
この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)"
システムのエンディアンを出力します。
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
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
が発生した場合、それはビッグエンディアンです。どちらの文字列も発生しない場合、またはさらに驚くべきことに両方が発生する場合、テストは失敗しています。
このアプローチが機能するのは、プログラムで計算される「fourcc」定数がマシンに依存しない値を持ち、エンディアンに関係なく同じ整数を示すためです。オブジェクトファイル内のストレージの表現は、ターゲットシステムのエンディアンに従っており、strings
の下の文字ベースのビューを介して表示されます。
2つのゼロガードワードにより、文字列が確実に分離されます。これは厳密には必要ありませんが、探している文字列が他の文字列に埋め込まれていないことを保証します。つまり、strings
はそれ自体を1行に出力します。
追伸USPELL
マクロは、再利用のためではなく、この特定の目的のために作成されているため、引数の挿入を括弧で囲みません。