Ich versuche ein paar Tricks mit dd zu machen. Ich dachte, es wäre möglich, einige Hex-Werte in einer Variablen namens "header" zu speichern, um sie in dd zu leiten.
Mein erster Schritt ohne Variable war folgender:
$ echo -ne "\x36\xc9\xda\x00\xb4" |dd of=hex
$ hd hex
00000000 36 c9 da 00 b4 |6....|
00000005
Danach habe ich folgendes versucht:
$ header=$(echo -ne "\x36\xc9\xda\x00\xb4")
$ echo -n $header | hd
00000000 36 c9 da b4 |6...|
00000004
Wie Sie sehen, habe ich meinen \x00
Wert in der $header
Variablen verloren. Hat jemand eine Erklärung für dieses Verhalten? Das macht mich verrückt.
linux
bash
shell-script
dd
Frank
quelle
quelle
bash: warning: command substitution: ignored null byte in input
.header="$(echo -ne "\x36\xc9\xda\x00\xb4")"; echo -n "$header" | hd
jedoch sein, dass dies nur das gleiche Ergebnis liefert.header="\x36\xc9\xda\x00\xb4"; echo -n "$header" | hd
, ist aber nicht dasselbe wie das Speichern der vom Menschen lesbaren Form.Antworten:
Sie können kein Null-Byte in einer Zeichenfolge speichern, da Bash Zeichenfolgen im C-Stil verwendet, die das Null-Byte für Terminatoren reservieren. Sie müssen Ihr Skript also neu schreiben, um einfach die Sequenz weiterzuleiten, die das Null-Byte enthält, ohne dass Bash es in der Mitte speichern muss. Zum Beispiel können Sie dies tun:
Beachten Sie übrigens, dass Sie nicht brauchen
echo
; Sie können Bash'sprintf
für viele andere einfache Aufgaben verwenden.Oder anstatt zu verketten, können Sie eine temporäre Datei verwenden:
Dies hat natürlich das Problem, dass die Datei
/tmp/mysequence
möglicherweise bereits vorhanden ist. Und jetzt müssen Sie weiterhin temporäre Dateien erstellen und deren Pfade in Zeichenfolgen speichern.Oder Sie können dies vermeiden, indem Sie die Prozessersetzung verwenden:
Der
<(command)
Operator erstellt im Dateisystem eine Named Pipe, die die Ausgabe von empfängtcommand
.hd
erhält als erstes Argument den Pfad zu dieser Pipe, die fast wie jede Datei geöffnet und gelesen wird . Weitere Informationen finden Sie hier: /unix//a/17117/136742 .quelle
zsh
wird es tun, aber nur im Nōn-POSIX-Modus.) Ich habe es tatsächlich untersucht, weil ich mich gefragt habe, ob es sich lohnt, dies inmksh
…sh
Emulation\0
nicht im Standardwert von liegt$IFS
.echo "$(printf 'a\0b')"
funktioniert immer noch OK in dersh
Emulation inzsh
.Sie können
zsh
stattdessen die einzige Shell verwenden, die das NUL-Zeichen in seinen Variablen speichern kann. Dieses Zeichen hat sogar den Standardwert von$IFS
inzsh
.Oder:
Oder
Oder
Beachten Sie jedoch, dass Sie eine solche Variable nicht als Argument oder Umgebungsvariable an einen Befehl übergeben können, der ausgeführt wird, da die Argumente und Umgebungsvariablen NUL-getrennte Zeichenfolgen sind, die an den
execve()
Systemaufruf übergeben werden (eine Einschränkung der API des Systems, nicht der Shell ). Inzsh
können Sie jedoch NUL-Bytes als Argumente an Funktionen oder integrierte Befehle übergeben.quelle
zsh
in Ihrer Frage die Syntax verwendet .echo -n $header
zu bedeuten , den Inhalt der zu übergeben$header
Variable als letztes Argumentecho -n
istzsh
(oderfish
oderrc
oderes
) Syntax, nicht -bash
Syntax. Inbash
hat das eine ganz andere Bedeutung . Im Allgemeinenzsh
ist es wieksh
(bash
die GNU-Shell ist mehr oder weniger ein Teilklonksh
der Unix-De-facto-Shell), aber mit den meisten Design-Besonderheiten der Bourne-Shell (und vielen zusätzlichen Funktionen und vielem mehr) benutzerfreundlicher / weniger erstaunlich).echo $(printf 'ab\0cd') | od -vAn -tx1c
Gibt `61 62 20 63 64 0a` aus, das ist ein Raum, in dem ein NUL existieren sollte.