Я пытаюсь сделать некоторые трюки с дд. Я думал, что было бы возможно сохранить некоторые шестнадцатеричные значения в переменной с именем "header", чтобы передать его в dd.
Мой первый шаг без переменной был такой:
$ echo -ne "\x36\xc9\xda\x00\xb4" |dd of=hex
$ hd hex
00000000 36 c9 da 00 b4 |6....|
00000005
После этого я попробовал это:
$ header=$(echo -ne "\x36\xc9\xda\x00\xb4")
$ echo -n $header | hd
00000000 36 c9 da b4 |6...|
00000004
Как вы можете видеть, я потерял свое \x00
значение в $header
переменной. У кого-нибудь есть объяснение этому поведению? Это сводит меня с ума.
linux
bash
shell-script
dd
Фрэнк
источник
источник
bash: warning: command substitution: ignored null byte in input
.header="$(echo -ne "\x36\xc9\xda\x00\xb4")"; echo -n "$header" | hd
но это просто дает тот же результат.header="\x36\xc9\xda\x00\xb4"; echo -n "$header" | hd
, но это не то же самое, что хранить читаемую человеком форму.Ответы:
Вы не можете хранить нулевой байт в строке, потому что Bash использует строки в стиле C, которые резервируют нулевой байт для терминаторов. Поэтому вам нужно переписать ваш скрипт, чтобы просто передать последовательность, содержащую нулевой байт, без необходимости сохранения Bash в середине. Например, вы можете сделать это:
Кстати, обратите внимание, что вам не нужно
echo
; Вы можете использовать Bashprintf
для этого и многих других простых задач.Или вместо цепочки вы можете использовать временный файл:
Конечно, это проблема того, что файл
/tmp/mysequence
может уже существовать. И теперь вам нужно продолжать создавать временные файлы и сохранять их пути в строках.Или вы можете избежать этого, используя подстановку процесса:
<(command)
Оператор создает именованный канал в файловой системе, которая получит выходcommand
.hd
в качестве первого аргумента получит путь к этому каналу, который он откроет и прочитает почти как любой файл. Вы можете прочитать больше об этом здесь: /unix//a/17117/136742 .источник
zsh
будет делать это, но только в режиме nōn-POSIX.) Я действительно изучил это, потому что мне было интересно, стоило ли это реализовать вmksh
…sh
эмуляции\0
нет значения по умолчанию$IFS
.echo "$(printf 'a\0b')"
все еще работает нормально вsh
эмуляции вzsh
.zsh
Вместо этого вы можете использовать единственную оболочку, которая может хранить символ NUL в своих переменных. Этот символ даже в значении по умолчанию$IFS
вzsh
.Или:
Или
Или
Однако обратите внимание, что вы не можете передать такую переменную как аргумент или переменную окружения команде, которая выполняется как аргументы, а переменные окружения - это разделенные NUL строки, передаваемые
execve()
системному вызову (ограничение системного API, а не оболочки ). Однакоzsh
вы можете передавать байты NUL в качестве аргументов в функции или встроенные команды.источник
zsh
синтаксис в своем вопросе.echo -n $header
иметь в виду , чтобы передать содержимое$header
переменной в качестве последнего аргументаecho -n
являетсяzsh
(или ,fish
или ,rc
илиes
) синтаксиса, а неbash
синтаксис. Воbash
, это имеет совсем другое значение . В более общем смыслеzsh
это похоже наksh
(bash
оболочка GNU, являющаяся более или менее частичным клономksh
, оболочка де-факто Unix), но с большинством конструктивных особенностей оболочки Bourne исправлены (и много дополнительных функций, и много более удобный / менее удивительный).echo $(printf 'ab\0cd') | od -vAn -tx1c
печатает `61 62 20 63 64 0a`, это место, где должен существовать NUL.