Как сказать, с обратным порядком байтов ли система Linux или с прямым порядком байтов?

NAT является просто механизмом, он не определяет ограничений, и любой такой было бы совершенно зависящим от реализации. Я сомневаюсь, мог ли кто-либо даже дать приблизительное среднее число, поскольку существует столько реализаций NAT там. Этот вопрос действительно не имеет смысла.

93
задан 4 July 2016 в 00:34
12 ответов

В Системе с обратным порядком байтов (Солярис на SPARC)

$ 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 и Sparc Solaris.

Мне был нужен только для оболочки (никакой Perl) решение, которое также работало над AIX/питанием и HPUX/Itanium. К сожалению, последние два не играют по правилам: AIX сообщает "6", и HPUX дает пустую строку.

Используя Ваше решение, я смог обработать что-то, что работало над всеми этими системами Unix:

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

Относительно решения Python кто-то отправил, оно не работает в Jython, потому что JVM рассматривает все как Большое. Если кто-либо может заставить это работать в Jython, отправьте!

Кроме того, я нашел это, которое объясняет порядок байтов различных платформ. Некоторые аппаратные средства могут работать в любом режиме в зависимости от того, что выбирает O/S: http://labs.hoffmanlabs.com/node/544


Если Вы собираетесь использовать awk, эта строка может быть упрощена до:

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

Для маленьких полей Linux, которые не имеют 'передозировки' (говорят, что OpenWrt) затем пробуют 'hexdump':

echo -n I | hexdump -o | awk '{ print substr($2,6,1); exit}'
112
ответ дан 28 November 2019 в 19:22
  • 1
    , Это - верхний регистр I (глаз), а не нижний регистр l (эль) между прочим. –  Paused until further notice. 23 July 2010 в 20:13

Этот сценарий Python должен работать на Вас:

#!/usr/bin/env python
from struct import pack
if pack('@h', 1) == pack('<h', 1):
    print "Little Endian"
else:
    print "Big Endian"
9
ответ дан 28 November 2019 в 19:22

Вот является более изящный Python коротким сценарием

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

код выхода 0 обратный порядок байтов средств и 1 прямой порядок байтов средств

или просто изменение sys.exit кому: print для печатаемого вывода

31
ответ дан 28 November 2019 в 19:22

Я нашел способ сделать это в Jython. Поскольку Jython (Python на JVM) работает на виртуальной машине, он всегда сообщает обратный порядок байтов, независимо от оборудования.

Это решение работает для 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
ответ дан 28 November 2019 в 19:22

https://raid.wiki.kernel.org/index.php/RAID_superblock_formats

Суперблок имеет длину 4 КБ и записывается в выровненный блок размером 64 КБ, который начинается минимум 64 КБ и меньше 128 КБ от конца устройства (то есть, чтобы получить адрес суперблока размером с устройства до кратного 64 КБ, а затем вычесть 64 КБ). Доступные размер каждого устройства - это количество места перед суперблоком, поэтому между 64 КБ и 128 КБ теряется, когда устройство встроено в MD 19 пакета util-linux команда lscpu начала включать поле, относящееся к порядку байтов. Итак, теперь вы можете просто использовать эту команду, чтобы узнать это:

$ lscpu | grep -i byte
Byte Order:            Little Endian

Это было подтверждено в Ubuntu 12.10 и CentOS 6. Так что я готов предположить, что большинство ядер Linux 3.0+ теперь предлагают это.

В Debian / В системах Ubuntu вы также можете использовать эту команду, не зная, когда она стала доступной:

$ dpkg-architecture | grep -i end
DEB_BUILD_ARCH_ENDIAN=little
DEB_HOST_ARCH_ENDIAN=little

Ссылки

10
ответ дан 28 November 2019 в 19:22

Если вы используете Linux недавно (почти все после 2012 года) , то lscpu теперь содержит следующую информацию:

$ lscpu | grep Endian
Byte Order:            Little Endian

Это было добавлено в lscpu ] в версии 2.19, которая находится в Fedora> = 17, CentOS> = 6.0, Ubuntu> = 12.04.

Обратите внимание, что я нашел этот ответ из этого потрясающего ответа на Unix.SE . В этом ответе много важной информации, этот пост - всего лишь его резюме.

35
ответ дан 28 November 2019 в 19:22
python -c "import sys; print(sys.byteorder)"

Он напечатает порядок байтов системы.

7
ответ дан 28 November 2019 в 19:22

Вы можете использовать формат файла ELF, чтобы определить порядок байтов в вашей системе. Например, выведите первые шесть байтов произвольного файла ELF в шестнадцатеричном формате:

xxd -c 1 -l 6 / bin / ls

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

Если последняя строка (шестеричный байт) - 01, в соответствии с форматом ELF , 01 будет прямым порядком байтов, а 02 - прямым порядком байтов.

Если у вас нет xxd на вашем ящике (и у вас есть busybox), попробуйте следующее:

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

7
ответ дан 28 November 2019 в 19:22

Однострочная команда на основе формата ELF:
hexdump -s 5 -n 1 / bin / sh

2
ответ дан 28 November 2019 в 19:22

Немного другое требование: мне нужен такой тест в сценарии конфигурации сборки программы, чтобы определить, является ли целевая машина компиляции битовой или прямой порядком байтов, без выполнения код . Скрипт должен поместить #define HAVE_LITTLE_ENDIAN 1 в заголовок config.h , иначе #define HAVE_LITTLE_ENDIAN 0 .

Целевая машина компиляции может отличаться с машины сборки, поскольку мы можем выполнять кросс-компиляцию, что также объясняет, почему тест не должен пытаться выполнить какой-либо скомпилированный код. Не может быть и речи о маленькой программе на языке C с оператором printf , выдающим ответ.

Возможное решение состоит в следующем. Мы генерируем файл с именем 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 выведут ее в отдельной строке.

P.S. макрос USPELL не помещает в скобки вставку аргументов, потому что он создан для этой конкретной цели, а не для повторного использования.

0
ответ дан 28 November 2019 в 19:22

вот решение, которое включает в себя полное неправильное использование кодов выхода оболочки posix. :

gawk/mawk/mawk2/nawk 'BEGIN { # system() returns 1 
                              # if little-endian.
                              # to check BE, change that -c 2 to -c 5
     print system("
          exit \140<<<\47\47 gnu-od | grep -c 2\140") }'

\47 = одинарная кавычка ascii, а \140 - это гравюра ascii

  • , за исключением gnu-gawk -S режима песочницы, который отключает system( )

что это делает выполнить это —>

exit ` <<<'' god | grep -c 2 `

внутри оболочки posix sh, в основном запрашивая gnu-od, чтобы показать вам 2-байтовые восьмеричные числа по умолчанию из одного символа \n (d=10).

в системах с прямым порядком байтов он отображается как 000012. Но в системах с обратным порядком байтов дополнительный байт заполнения заставляет gnu-od повышать восьмеричные числа. десятичное число 10 * 256 = 2560 = 5x8x8x8, поэтому результирующее 2-байтовое восьмеричное число равно 005000. Затем используйте функцию счетчика grep, чтобы найти либо 2, либо 5.

Коды выхода должны быть такими, что 0 означает успех, а каждое большее число означает какую-то ошибку. но поскольку счетчик grep уже помог нам инвертировать это, возвращаемый «код выхода» системной команды уже имеет логическое значение awk true (1) и false (0).

0
ответ дан 6 August 2021 в 06:53

Мне немного не нравится ответ, который опирается на формат ELF, так как он не везде используется (это могут быть скрипты, или другой binfmt, или даже система cygwin). Вот относительно переносимый, который опирается только на POSIX и шестнадцатеричный дамп(поэтому совместим с busybox, если вы стремитесь к совместимости с POSIX, вместо этого следует использовать awk):

if test `printf '\0\1' | hexdump -e '/2 "%04x"'` -eq 0100
then
    echo little
else
    echo big
fi

Также проверьте средний -endian:

case `printf '\0\1\2\3' | hexdump -e '/4 "%08x"'` in
03020100) echo little;;
00010203) echo big;;
01000302) echo mid-big;;
02030001) echo mid-little;; # these two might be swapped, adjust accordingly
*) echo unknown endianness
esac

Как это работает? Printf печатает байт за байтом в следующем порядке: 00 01.

Шестнадцатеричный дамп был адаптирован из здесь. /4указывает применить форматирование сразу к группам из 4 байтов. "%08x"— это выходной формат (8 шестнадцатеричных символов с ведущим 0). Идея здесь в том, что он будет читать число в его родном порядке байтов и отображать его в «удобочитаемом» формате с прямым порядком байтов. X -> Y endian — это тот же обмен, что и Y -> X. Таким образом, big -> native выполняется здесь с помощью шестнадцатеричного дампа, хотя предполагается, что native -> big.

Если у кого-то есть математическое объяснение этому, мне было бы любопытно, кстати. Замена два раза эквивалентна тождеству.

0
ответ дан 29 September 2021 в 12:37

Теги

Похожие вопросы