Wenn Sie bei Shell-Dienstprogrammen bleiben möchten, können Sie head
eine Anzahl von Bytes extrahieren und od
ein Byte in eine Anzahl konvertieren.
export LC_ALL=C # make sure we aren't in a multibyte locale
n=$(head -c 1 | od -An -t u1)
string=$(head -c $n)
Dies funktioniert jedoch nicht für Binärdaten. Es gibt zwei Probleme:
Befehlssubstitutions $(…)
strips final newlines in der Befehlsausgabe. Es gibt eine relativ einfache Problemumgehung: Stellen Sie sicher, dass die Ausgabe mit einem anderen Zeichen als einer neuen Zeile endet, und entfernen Sie dann dieses eine Zeichen.
string=$(head -c $n; echo .); string=${string%.}
Bash ist, wie die meisten Shells, schlecht im Umgang mit Null-Bytes . Ab Bash 4.1 werden null Bytes einfach aus dem Ergebnis der Befehlssubstitution entfernt. Dash 0.5.5 und pdksh 5.2 haben dasselbe Verhalten, und ATT ksh stoppt das Lesen beim ersten Null-Byte. Im Allgemeinen sind Shells und ihre Dienstprogramme nicht auf den Umgang mit Binärdateien ausgerichtet. (Zsh ist die Ausnahme, es unterstützt null Bytes.)
Wenn Sie über Binärdaten verfügen, möchten Sie zu einer Sprache wie Perl oder Python wechseln.
<input_file perl -e '
read STDIN, $c, 1 or die $!; # read length byte
$n = read STDIN, $s, ord($c); # read data
die $! if !defined $n;
die "Input file too short" if ($n != ord($c));
# Process $s here
'
<input_file python -c '
import sys
n = ord(sys.stdin.read(1)) # read length byte
s = sys.stdin.read(n) # read data
if len(s) < n: raise ValueError("input file too short")
# Process s here
'
Gilles 'SO - hör auf böse zu sein'
quelle
quelle
read -N
stoppt bei null Bytes, daher ist dies kein geeigneter Weg, um mit Binärdaten zu arbeiten. Im Allgemeinen können andere Shells als zsh nicht mit Nullen umgehen.Wenn Sie in der Lage sein möchten, mit Binärdateien in der Shell umzugehen, ist die beste Option (nur?), Mit dem Hexdump- Tool zu arbeiten.
Nur X Bytes lesen:
Lese die Länge (und arbeite mit 0 als Länge) und dann "string" als Byte-Dezimalwert:
quelle
UPDATE (im Nachhinein): ... Diese Frage / Antwort (meine Antwort) lässt mich an den Hund denken, der das Auto immer wieder verfolgt. Eines Tages holt er schließlich das Auto ein. Okay, er hat es verstanden, aber er kann wirklich nicht viel damit anfangen ... Dieser Anser "fängt" die Saiten, aber dann kann man nicht viel damit anfangen, wenn sie Null-Bytes eingebettet haben ... (also eine große +1 an Gilles Antwort .. hier ist möglicherweise eine andere Sprache in Ordnung.)
dd
Liest alle Daten ... Es wird mit Sicherheit nicht bei Null als "Länge" aufgehen ... aber wenn Sie \ x00 irgendwo in Ihren Daten haben, müssen Sie kreativ sein, wie Sie damit umgehen;dd
hat keine propblems damit, aber Ihr Shell-Skript wird Probleme haben (aber es hängt davon ab, was Sie mit den Daten tun möchten) ... Im Folgenden wird grundsätzlich jeder "Datenstring" in eine Datei mit einem Zeilenteiler zwischen den einzelnen Strins ausgegeben ...btw: Sie sagen "Zeichen", und ich nehme an, Sie meinen "Byte" ...
aber das Wort "Zeichen" ist in diesen Tagen von UNICODE, in denen nur der 7-Bit-ASCII-Zeichensatz ein einzelnes Byte pro Zeichen verwendet, mehrdeutig geworden ... Und auch innerhalb des Unicode - System Bytezählwerte auf dem Verfahren variieren in Abhängigkeit der Codierung Zeichen , z. B. UTF-8, UTF-16 usw.
Hier ist ein einfaches Skript, um den Unterschied zwischen einem Text- "Zeichen" und Bytes hervorzuheben.
Wenn Ihre Länge Zeichen 1 Byte lang und weist auf eine Byte-Länge , dann sollte dieses Skript den Trick tun, auch wenn die Daten Unicode - Zeichen enthält ...
dd
sieht nur Bytes unabhängig von einer Lokalisierungs - Einstellungen ...Dieses Skript
dd
liest die Binärdatei und gibt die durch einen "====" - Teiler getrennten Zeichenfolgen aus. Testdaten finden Sie im nächsten SkriptAusfahrt
Dieses Skript erstellt Testdaten, die ein 3-Byte-Präfix pro Zeile enthalten ...
Das Präfix ist ein einzelnes UTF-8-codiertes Unicode-Zeichen ...
quelle
/dev/urandom
meisten Unices erhalten. Und zufällige Testdaten sind nicht die besten Testdaten. Sie sollten darauf achten, schwierige Fälle wie hier Nullzeichen und Zeilenvorschub an Grenzstellen zu behandeln.Dieser kopiert einfach eine Binärdatei:
quelle