прохождение дд пропустить | искать смещение как шестнадцатеричное


11
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=3 2> /dev/null
d
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=0x3 2> /dev/null
f

Почему вторая команда выводит другое значение?

Можно ли передать смещение skip | seek ddкак шестнадцатеричное значение?

Ответы:


18

Почему вторая команда выводит другое значение?

По историческим причинам ddсчитается xоператором умножения. Так 0x3что оценивается как 0.

Можно ли передать смещение skip | seek в dd в виде шестнадцатеричного значения?

Не напрямую, насколько я знаю. Помимо умножения с использованием оператора x, вы можете добавлять к любому числу суффикс b«умножать на 512» (0x200) и K«умножать на 1024» (0x400). С ГНУ д.д. вы можете также использовать суффиксы M, G, T, P, E, Zи Yозначает умножить на 2 в степени 20, 30, 40, 50, 60, 70, 80 или 90, соответственно, и вы можете использовать верхний или нижний регистр , за исключением для bсуффикса. (Существует много других возможных суффиксов. Например, EBозначает «умножить на 10 18 » и PiBозначает «умножить на 2 50 ». См. info coreutils "block size"Дополнительную информацию, если у вас установлена ​​GNU.)

Вы можете найти вышеупомянутое тайное, анахроничное и вызывающее до абсурда. Не волнуйтесь: вы не одиноки. К счастью, вы можете просто проигнорировать все это и использовать вместо этого арифметическую подстановку вашей оболочки (работают bash и другие совместимые с Posix оболочки, а также некоторые не-Posix оболочки). Оболочка понимает шестнадцатеричные числа и допускает полный диапазон арифметических операторов, записанных обычным способом. Вам просто нужно окружить выражение $((...)):

# dd if=2013-Aug-uptime.csv bs=1 count=$((0x2B * 1024)) skip=$((0x37))

Обратите внимание, что $((...))это арифметическое расширение POSIX, оно вообще не относится к bash, вам не нужно использовать bashего, подойдет любая оболочка POSIX. Однако обратите внимание, что во многих оболочках, в том числе bash, он подвергается разбиению по словам, поэтому его следует заключать в кавычки.
Стефан Шазелас

@StephaneChazelas: Это правда, это не специфично для bash. Однако, это не нуждается в кавычках. (Posix: «Выражение должно обрабатываться так, как если бы оно было в двойных кавычках, за исключением того, что двойные кавычки внутри выражения не обрабатываются специально.») Если в выражении была переменная, и ее значение содержало разделитель, тогда это не будет действительное число; размещение цитат вокруг $((...))ничего не изменит. Единственный случай, когда я могу придумать, где цитаты могли бы что-то сделать, это если бы у вас было что-то подобное, IFS=4но это вызвало бы всевозможный хаос.
Ричи

Вы цитируете раздел о том, что внутри $((...)). POSIX ясно, что расширение $((...))является предметом разделения слов . Если оставить любое расширение команды / арифметики / переменной без кавычек в списке, это оператор split + glob. Установка IFS = 4 не вызовет всевозможных проблем, если вы не используете оператор split + glob там, где он не нужен / не нужен, и устанавливаете IFS каждый раз, когда вам нужен этот оператор split + glob.
Стефан Шазелас

@StephaneChazelas: да, числовой результат может быть разбит на слова. Но это целое число. Если вы установите IFSчто-то, что включает в себя цифры, то, что я не верю, что я когда-либо делал, то вам придется цитировать. Предположительно, если бы кто-то делал это, он бы осознавал необходимость, поскольку вряд ли это можно сделать случайно. Или, по крайней мере, я вряд ли это сделаю, точка. Я не хочу говорить за тебя.
Ричи

1
@ogurets: какую оболочку вы используете? (Пожалуйста, включите версию).
Ричи

0

Я знаю, что это старая ветка, но проблема по-прежнему актуальна, как и прежде, особенно когда идиоты, подобные мне, уходят и непреднамеренно вызывают и извлекают 'cp fileA fileB' из истории bash, когда fileB еще не зарегистрирован, чтобы git не поддержал и содержит несколько часов кодирования после ночи: - /

Благодаря концепциям в этой теме я смог полностью восстановить мой потерянный файл, однако потерял свой на удаленном виртуальном частном сервере с 32-гигабайтным диском и очень небольшим объемом ОЗУ (под управлением Ubuntu 18.04), а также все мои попытки с использованием «grep» в качестве выше бы быстро умереть с «недостаточным объемом памяти»

В моем случае это было то, hexdump -C /dev/sdX1 | grep 'shortString'что пришло мне на помощь. В отличие от grep, он отображает только очень укороченное представление гекса в ASCII, поэтому очень важно искать только короткую уникальную строку и помнить, что даже это может быть перенесено. После того, как он вывел некоторый шестнадцатеричный адрес, где было совпадение, я смог использовать 'dd' аналогично тому, как описано выше, за исключением того, что я обнаружил, что он по умолчанию имеет размер блока 4096, так что мне пришлось не только преобразовать адрес шестнадцатеричных байтов в десятичный, но разделить его на 4096, чтобы масштабировать его до 4k блоков для параметра пропуска dd - бесполезно, если это число слишком велико для dd, сообщение об ошибке выглядит так, как будто оно жалуется skip=на недействительность, а не на число, переданное ему ,

Престижность людям, которые добавили советы по использованию bash с $((0xabcd))конвертированием easilty obtaion hex-> dec :-)

Просто мое последнее слово - в моем случае было несколько копий одного и того же файла, которые были в непосредственной близости. Но вычитая наименьший адрес из наивысшего адреса, указанного в hexdump, я смог идентифицировать область размером ~ 5 МБ, содержащую все возможные копии, что означало, что я могу нацелить dd на самый низкий адрес и извлечь всю эту область во временный файл. Редактор Vim теперь обрабатывает двоичный контент довольно изящно, поэтому вы можете просмотреть временный файл и изменить его при необходимости.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.