Folgendes Problem: In einem bash-Skript sollen Eingabezeilen verarbeitet werden. Die Eingabezeilen sind aber nicht mit Newlines beendet, sondern mit Nullbytes (ASCII-NUL, \0). Außerdem können Newlines und anderer Whitespace korrekter und zu erhaltender Inhalt der Zeilen sein.
Das Whitespace-Problem ist schnell gelöst: Einfach die shellinterne Variable IFS (internal field separator) setzen. Aber wie liest man NULL-terminierte Zeilen ein?
Dieses sehr informative, aber englische Blogeintrag zum Thema bash und read bietet die Lösung. Das Shell-Builtin read versteht unter anderem die Option „-d <delim>„. Darüber kann man den Trenner für Eingabezeilen festlegen. Auch Nullbytes kann man festlegen – wenn man weiß, wie, denn der erste Anlauf ‚\0‘ funktioniert nicht!
Korrekte Lösung: Einfach einen Leerstring als Delimiter übergeben.
read -d “ LINE
Im Zusammenhang sähe eine Lösung dann so aus:
# Ursprünglichen IFS sichern
OLD_IFS=“$IFS“
# IFS leeren, damit Whitespace nicht verändert wird
IFS=““
find . -print0 | while read -d “ LINE; do
# In LINE befindet sich nun eine unveränderte Ausgabezeile von find(1)
done
#Alten IFS restaurieren
IFS=“$OLD_IFS“
ich hoffe, das hilft mal irgendwem weiter.
Jochen
Es hat grad jemandem weitergeholfen. 🙂
Danke!
Hm. Wenn ich die Frage richtig verstehe, dreht es sich darum, dass das erste Trennzeichen die Eingabe beendet? So ist das eigentlich gedacht, schließlich beendet ja auch der erste Newline in der Eingabe das read, wenn man nicht mit -d herumspielt. Nullbytes sind eben deshalb praktisch, weil sie in normalen Daten nicht vorkommen. Läßt man dann find über die print0-Aktion das Nullbyte als Separator setzen, hat man alles wie gewünscht.
Ansonsten mail mir mal Dein Problem, vielleicht wird’s dann leichter zu verstehen.
Jochen
irgendwie steige ich nicht dahinter. aber das liegt daran, daß ich noch relativ frisch bin in sachen bash.
ich hab das problem, daß ‚read -d a variable‘ nur ein zeichen nimmt. ich brauche aber was, was zu 99% nicht im text vorkommt den ich einer varibale zuweisen will.