[linux-l] Quoting, Parsing, Byte-Streams (was: find(1) mit und ohne xargs(1))

Volker Grabsch vog at notjusthosting.com
Mi Okt 12 13:06:53 CEST 2005


On Tue, Oct 11, 2005 at 12:35:23PM +0200, Oliver Bandel wrote:
> [...]
> > Leider funktionieren nicht alle Tools so, vorallem bei Konvertern
> > (ps2pdf, convert, pnmtojpeg, ...) vermisse ich das.
> 
> Nun, die müssen eh die gesamten Daten erst mal ins RAM laden
> und dann wüst drauf herum werkeln, denk ich mal.

Bitte lass uns im Kontext bleiben. Zur Veranschaulichung nehme
ich einfach mal ein, es gäbe ein "pnm2jpg", das mehrere PNM-Dateien
in ihre zugehörigen JPEGs umwandelt. Vielleicht wird es die PNM-Datei
komplett in dem RAM lesen und darauf operieren, kann durchaus sein,
vielleicht geht's auch effizienter, aber der Punkt ist: Darum geht
es nicht!

Es geht darum, was passiert, wenn das Programm *mehere* PNM-Dateien
bekommt. Wenn es wie folge aufgerufen wird:

	pnm2jpg datei1.pnm datei2.pnm ... datei1000.pnm

dann liegt die gesamte Dateiliste im RAM. Kann das Programm hingegen
seine Dateiliste von Stdin lesen, so kann es schon losarbeiten, während
"find -name '*.pnm' ..." arbeitet. Diese Variante hat auch den Vorteil,
dass man im voraus nicht wissen braucht, wieviele es werden.

Gut, eine große Dateiliste im RAM ist noch nicht wirklich ein Hammer
an Verschwendung, jedoch gibt es außerdem ein Limit für die Anzahl der
Argumente. Eine größere Dateiliste per Stream zu übergeben ist daher
IMHO die sauberste und natürlichste Weise, mit diesem Problem umzugehen.

> > Die können nicht
> > mal mehrere Input-Dateien als Argumente entgegen nehmen, was ich
> > wiegesagt aber eh nicht für allzu sinnvoll halte.
> 
> Ist ja u.U. auch schwierig, wenn man mehrere Dateien aus stdin
> liest und die in z.B. andere Dateien ablegen soll.
> Wie will man die Sachen da unterscheiden? Und wie ggf.
> die Namen der Ausgabe entsprechend zuordnen?

Nonsense. Es ging nie darum, 100 PNM-Dateien auf einmal durch in das
Programm zu jagen, sondern es ging nur um die Dateiliste. Ich finde
es unangebracht von dir, im Nachhinein den Kontext ändern zu wollen.

Davon abgesehen: PNM-Dateien haben einen Header, wo AFAIK drin steht,
wieviel zu erwarten ist. Falls das nicht ausreicht, kann man auch
Tar-Archive nehmen, das ist ja letztlich ein "multiple file stream"
Format.

> > Das geht in die selbe Richtung wie unsere Iterator vs. Listen
> > Diskussion: Wenn ich eine variable Datenmenge (z.B. Dateiliste)
> > habe, dann will ich sie erstmal als Iterator bekommen (d.h. als
> > Stream, von ner Pipe), und nicht den Umweg über Listen gehen
> > (d.h. per xargs, das alles sammelt und mit einem Schlag dem
> > aufgerufenden Programm übergibt).
> 
> Diese Konzepte machen aber nicht in jedem Falle Sinn.
> Via CLI kann man die Parameter ganz gut voneinander trennen,
> bei stdin müsste man ein eigenes Protokoll entwickeln, das zwischen
> Steuerdaten (Filenamen) und Nutzdaten 8die eigentlichen
> Dateiinhalte) unterscheidet.

Auch das ist falsch. In C gibt es ohnehin die Einschränkung, dass
String per 0x00 getrennt werden, d.h. sie können den ASCII-Wert 0
nicht enthalten. Die Dateiliste im Stdin-Stream mit 0x00 zu
separieren ist also letztlich das gleiche wie die Parameterübergabe.

Darüberhinaus gebe ich dir aber recht, dass es in der Tat viele
Probleme gibt, die man vermeiden könnte, wenn in der Unix-Architektur
die kleinste Grundeinheit nicht der Byte-Stream, sondern der String-
Stream wäre, bzw. wenn es direkten Support für die Übergabe von
Datenstrukturen (structs und lists) gäbe.

> Da lkandet man dann wieder beim Quoting-Problem, das wir schon
> beim Parser-zeugs besprochen hatten: Metacharacters, also
> z.B. \ usw., oder man muß die Eingabedaten auf bestimmte Zeichen
> beschränkt wissen, ...

Nö, siehe oben, das geht in dem konkreten Fall "Stringliste" auch
einfacher. Wenn jedoch kompliziertere Datenstrukturen übergeben werden,
dann wäre es in der Tat wünschenswert, wenn man Strukturen und Listen
und gegeben hätte, statt sie irgendwie selbst codieren zu müssen. Und
der einzige wirklich Standard, den wir da haben, XML, ist dermaßen
"bloated" ... würden im Kernel nicht Bytes zwischen den Prozessen,
sondern Strings oder Strukturen in den Pipes übertragen werden, könnte
man sich dan ganzen Quoting / Parsing Mist ersparen. Aber so weit wurde
selbst in Plan9 leider nicht gegangen.

In Plan9 ist zwar *wirklich* alles eine Datei bzw. ein Stream ... man
killt Prozesse durch löschen einer bestimmten "Datei" ... und jeder kann
einen eigenen Filesystem-Handler schreiben, um zu kommunizieren, also
alles in allem eine sehr, sehr schöne Architektur. Sie haben alle Unix-
Ideen umgesetzt, aber *wirklich*, und nicht so halbherzig wie die
POSIX-Systeme. Dennoch ist die unterste Schicht leider immer noch der
Byte-Stream.


Viele Grüße,

	Volker

-- 
Volker Grabsch
---<<(())>>---
Administrator
NotJustHosting GbR



Mehr Informationen über die Mailingliste linux-l