Próbuję zrobić kilka sztuczek z dd. Myślałem, że możliwe będzie przechowywanie niektórych wartości szesnastkowych w zmiennej o nazwie „nagłówek”, aby przesłać je do dd.
Mój pierwszy krok bez zmiennej był następujący:
$ echo -ne "\x36\xc9\xda\x00\xb4" |dd of=hex
$ hd hex
00000000 36 c9 da 00 b4 |6....|
00000005
Potem próbowałem tego:
$ header=$(echo -ne "\x36\xc9\xda\x00\xb4")
$ echo -n $header | hd
00000000 36 c9 da b4 |6...|
00000004
Jak widać straciłem swoją \x00
wartość w $header
zmiennej. Czy ktoś ma wyjaśnienie tego zachowania? Doprowadza mnie to do szału.
linux
bash
shell-script
dd
Szczery
źródło
źródło
bash: warning: command substitution: ignored null byte in input
.header="$(echo -ne "\x36\xc9\xda\x00\xb4")"; echo -n "$header" | hd
taki sam wynik.header="\x36\xc9\xda\x00\xb4"; echo -n "$header" | hd
, ale nie jest tym samym, co przechowywanie postaci czytelnej dla człowieka.Odpowiedzi:
Nie można przechowywać bajtu zerowego w ciągu, ponieważ Bash używa ciągów w stylu C, które rezerwują bajt zerowy na terminatory. Musisz więc przepisać skrypt, aby po prostu potokować sekwencję zawierającą bajt zerowy, bez konieczności zapisywania go przez Bash na środku. Na przykład możesz to zrobić:
Przy okazji zwróć uwagę, że nie potrzebujesz
echo
; możesz użyć Bashaprintf
do wykonania wielu innych prostych zadań.Lub zamiast tworzenia łańcuchów możesz użyć pliku tymczasowego:
Oczywiście ma to problem polegający na tym, że plik
/tmp/mysequence
może już istnieć. A teraz musisz nadal tworzyć pliki tymczasowe i zapisywać ich ścieżki w ciągach.Lub możesz tego uniknąć, stosując substytucję procesu:
<(command)
Operator tworzy nazwanego potoku w systemie plików, który otrzyma wyjściecommand
.hd
otrzyma jako swój pierwszy argument ścieżkę do tego potoku - który otworzy i przeczyta prawie jak każdy plik. Możesz przeczytać więcej na ten temat tutaj: /unix//a/17117/136742 .źródło
zsh
zrobię to, ale tylko w trybie nōn-POSIX). Właściwie to przyjrzałem się, ponieważ zastanawiałem się, czy warto to zaimplementować wmksh
…sh
emulacji\0
nie ma domyślnej wartości$IFS
.echo "$(printf 'a\0b')"
nadal działa OK wsh
emulacji wzsh
.Zamiast tego możesz użyć,
zsh
która jest jedyną powłoką, która może przechowywać znak NUL w jego zmiennych. Ta postać ma nawet domyślną wartość$IFS
inzsh
.Lub:
Lub
Lub
Należy jednak pamiętać, że nie można przekazać takiej zmiennej jako argumentu lub zmiennej środowiskowej do komendy, która jest wykonywana, ponieważ argumenty i zmienne środowiskowe są łańcuchami rozdzielanymi przez NUL przekazywanymi do
execve()
wywołania systemowego (ograniczenie interfejsu API systemu, a nie powłoki ). Wzsh
, można jednak przejść NUL bajty jako argumenty funkcji lub wbudowanych poleceń.źródło
zsh
składni w swoim pytaniu.echo -n $header
oznaczać przekazać zawartość$header
zmiennej jako ostatni argumentecho -n
jestzsh
(lubfish
lubrc
lubes
) składnia, niebash
składnia. Wbash
, który ma zupełnie inne znaczenie . Bardziej ogólniezsh
jest podobnyksh
(bash
powłoka GNU, będąca mniej więcej częściowo klonemksh
, de facto uniksowa powłoka Unixa), ale z naprawioną większością charakterystycznych cech projektowych powłoki Bourne'a (oraz z wieloma dodatkowymi funkcjami i wieloma bardziej przyjazny dla użytkownika / mniej zadziwiający).echo $(printf 'ab\0cd') | od -vAn -tx1c
wypisuje `61 62 20 63 64 0a`, czyli przestrzeń, w której powinien istnieć NUL.