Perl Pack Распаковать переменную оболочки

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

Чтобы все упростить, я обойду код, который мне удалось заставить работать, и начну с:

rawHex=0x41000000
echo $(perl -e 'print unpack "f", pack "L", $ENV{rawHex}')

Когда я выполняю этот код, результат равен 0. Однако, если бы я выполнил код, не пытаясь получить значение переменной оболочки:

echo $(perl -e 'print unpack "f", pack "L", 0x41000000')

Результат 8, чего я и ожидаю.

Я был бы признателен за любую помощь в том, как я могу обновить свое выражение Perl, чтобы правильно интерпретировать значение переменной оболочки. Спасибо.


person Dan    schedule 13.11.2019    source источник
comment
Переменная, которую вы определяете в оболочке, является локальной, а не переменной среды, поэтому она не видна %ENV. Вам нужно экспортировать его, export rawHex=... (или просто export rawHex, если он уже настроен). Теперь он будет у %ENV. (В качестве альтернативы вы можете передать его в свою программу командной строки Perl в качестве аргумента командной строки или переключателя)   -  person zdim    schedule 14.11.2019
comment
Я попытался убедиться, что переменная была доступна таким образом, оценив: echo $(perl -e 'print $ENV{rawHex}'), и результат был 0x41000000, как и ожидалось.   -  person Dan    schedule 14.11.2019
comment
См. это сообщение для объяснения, а затем этот (со ссылками) тоже должен быть полезен   -  person zdim    schedule 14.11.2019
comment
(чтобы завершить эти комментарии: вам также нужно hex. Теперь все это делается в икегами отвечать)   -  person zdim    schedule 14.11.2019


Ответы (2)


export rawHex=0x41000000
perl -le'print unpack "f", pack "L", hex($ENV{rawHex})'

Как вы обнаружили, ваш код не эквивалентен следующему:

perl -e 'print unpack "f", pack "L", 0x41000000'

Ваш код эквивалентен следующему:

perl -e 'print unpack "f", pack "L", "0x41000000"'

Как и "0x41000000", $ENV{rawHex} создает строку 0x41000000. С другой стороны, 0x41000000 дает число один миллиард девяносто миллионов пятьсот девятнадцать тысяч сорок.

Чтобы преобразовать шестнадцатеричное представление числа в число, которое оно представляет, используется hex. Просто замените $ENV{rawHex} на hex($ENV{rawHex}).

export rawHex=0x41000000
perl -le'print unpack "f", pack "L", hex($ENV{rawHex})'

-l вызывает добавление перевода строки к выводу, поэтому вам не нужно использовать echo. Не стесняйтесь удалять l, если вы на самом деле не используете echo.

Генерация кода (как было предложено в предыдущем ответе) - ужасная практика.

person ikegami    schedule 14.11.2019

Рабочее решение есть

rawHex=0x41000000
echo $(perl -e "print unpack 'f', pack 'L', ${rawHex}")

В вашем коде две проблемы. Во-первых, в bash переменные в одинарных кавычках ' не будут оцениваться. Вот почему я перевернул одинарные и двойные кавычки в вашем примере.

Вторая проблема заключается в использовании ENV. Я не уверен, почему вы его используете, но он вам не нужен.

person Michele Dorigatti    schedule 13.11.2019
comment
Я пробовал перестановку этого, но у меня был ненужный набор скобок, и он не возвращал согласованный результат. Теперь, когда я удалил скобки, это работает. Спасибо! - person Dan; 14.11.2019
comment
Не забудьте принять мой ответ, если он решил вашу проблему;) - person Michele Dorigatti; 14.11.2019
comment
Хотя технически это правильно (это сработает), я должен выступить против инъекций - они открывают весь (однострочный Perl) скрипт для неизвестно чего. Есть и другие способы передать переменную оболочки в программу, один из которых — с помощью export, когда она становится переменной окружения и к ней можно получить доступ в %ENV - person zdim; 14.11.2019
comment
Re переменные в одинарных кавычках ' не будут оцениваться., это хорошо. Генерация кода — не лучшая идея. - person ikegami; 14.11.2019