Du bist relativ nahe dran, glaube ich, aber von manchen Dingen hast du
eine falsche Vorstellung – so meine Vermutung. ☺
„Kanal/Deskriptor/Pipe“ ist nicht dasselbe. „Kanal“ und „Deskriptor“
kann man synonym verwenden, aber eine Pipe ist etwas anderes. Dazu
später mehr. Ich bleibe jetzt mal beim Wort „Deskriptor“, weil ich das
hier im Thread von Anfang an benutzt habe.
In Deskriptoren werden auch keine Rückgabewerte gespeichert. Ich glaube
zwar, dass ich das die Tage schonmal aufgeschrieben habe, aber macht ja
nix: Wenn du in einem Programm eine Datei öffnen willst, dann musst du
sie zunächst natürlich über ihren Pfad adressieren. Du sagst also
sinngemäß in C-ähnlichem Pseudocode:
open("/home/foo/datei.txt");
Aber wie willst du nun die geöffnete Datei ansprechen, um etwas
hineinzuschreiben? Du könntest sie natürlich wieder mit ihrem Pfad
ansprechen und etwas wie das hier machen:
write("/home/foo/datei.txt", "das hier soll geschrieben werden");
Das ist aber ziemlich umständlich, da jedesmal den ganzen Pfad
hinzuschreiben. Unter anderem um diese Adressierung etwas einfacher zu
machen, gibt es Deskriptoren. Das heißt, beim Öffnen der Datei passiert
eigentlich etwas in dieser Richtung:
int fd = open("/home/foo/datei.txt");
In der Variablen fd
steht dann eine Zahl, zum Beispiel die 3. Und beim
Schreiben kannst du dann:
write(fd, "das hier soll geschrieben werden");
/* oder: */
write(3, "das hier soll geschrieben werden");
Allgemein formuliert gibt ein Deskriptor also ein Ziel für einen
Schreibvorgang an – oder eine Quelle für einen Lesevorgang oder beides.
Was genau sich hinter dem Deskriptor „3“ befindet, das spielt dann
nämlich auch (fast) gar keine Rolle mehr. Deskriptoren sind eine sehr
praktische Abstrahierung weg von der Idee „schreibe in Datei“ hin zu
„schreibe auf Deskriptor“. Die Daten landen dann auch nicht „im“
Deskriptor, sondern in dem Ziel, auf das der Deskriptor zeigt.
Okay? ☺
So, was ist jetzt eine Pipe? Eine Pipe brauchst du überhaupt erst dann,
wenn du zwei Prozesse miteinander sprechen lassen möchtest. Also im
bisherigen Beispiel: ls
und wc
. Dabei soll wc
auf das hören, was
ls
ihm zu sagen hat.
Wie löse ich das Problem nun möglichst einfach, ohne viele neue
Programmierschnittstellen einzuführen? Ganz einfach: Mit Deskriptoren.
Wie oben schon gesagt, ist so ein Deskriptor total abstrakt und das
Programm, das auf ihn schreibt, interessiert sich nicht dafür, was
„hinter“ dem Deskriptor ist.
Nun stell dir eine Pipe als ein Paar von Deskriptoren vor: Auf einem
kannst du schreiben und auf dem anderen kannst du das lesen, was auf den
ersten geschrieben wurde. Deine beiden Programme werden gestartet und
ihnen werden die passenden Deskriptoren mitgegeben: ls
bekommt das
Ding zum Schreiben, wc
das zum Lesen. Fertig ist die Pipe.
So viel erstmal allgemein zu Deskriptoren und Pipes. Macht es das etwas
klarer? Mir rennt jetzt leider die Zeit davon, sodass ich auf deine
konkreteren Fragen nicht mehr genauer eingehen kann. Vielleicht heute
abend oder morgen bzw. am Wochenende. Ansonsten wird sicher jemand
anders noch ein paar Worte dazu sagen. ☺