• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

rekursives Pipen möglich?

bakaroo

Newbie
Hallo, nach langen auch mal wieder eine Frage von mir:

Ich habe hier ein Programm, das während des Ablaufs via Tastatureingaben gesteuert, und Statusangaben auf stdout ausgibt.

dieses soll nun via shell-script ferngesteuert werden, welches wiederum auf andere Ereignisse reagiert:
Code:
Ereignisclient         --->shell-Script zum Übersetzen    ->Programm -->
(gibt Daten via stdout aus)               /\__________________________!
das ganze kann ja mustergültig in einer Pipe laufen:
Code:
 client | Shell  | Programm
....nur wie mach ich die Rückführung der Statusmeldungen vom Programm auf das script? schreib ich einfach die stdout des Programms in eine Datei, und check die im script mit tail?
Gibt es eine elegantere Lösung? oder gibt es ein rekursives Pipen ?

Grübelnd
Bakaroo
 
A

Anonymous

Gast
....nur wie mach ich die Rückführung der Statusmeldungen vom Programm auf das script? schreib ich einfach die stdout des Programms in eine Datei, und check die im script mit tail?
Gibt es eine elegantere Lösung? oder gibt es ein rekursives Pipen ?

die Ausgaben in eine Datei zu schreiben und diese auszuwerten, könnte man machen, evtl muss man sich was wegen der Synchronisierung einfallen lassen.

natürlich kann man auch andere Pipe erzeugen, allerdings nicht ganz so komfortabel wie einfach | Man braucht dazu schon etwas Wissen über Interprozesskommunikation dann kann man entweder Named- oder Unamed Pipe und oder gezielt erzeugte Kommunikationskanäle in den Prozessen für solche Rückmeldungen ausnutzen. Eignet sich auch wenn mehr als 2 Prozesse miteinander kommunizieren müssen. einige Grundlagen dazu findest du in man bash unter Stichworten wie Redirection und File Descriptor.

Es gibt aber auch ein Programm expect (meist nicht installiert), Das beruht auf einer Scriptsteuerung die geziehlt die Ausgaben der aufgerufenen Programme auswertet und man kann dort auf jede Ausgabe unterschiedlich reagieren. Allerdings sollte man schon etwas Erfahrungen mit Pattern wie sie zB grep sed awk benutzen mitbringen.
Wenn also größere Interaktive Sachen zu programmieren sind, dann lohnt es sich mit expect und autoexpect zu beschäftigen.

Mit Perl gibt es sicher auch Möglichkeiten, aber mit Perl hab ich gar nichts am Hut.

Hier mal ganz einfaches Beispiel einer Rückkopplung mit named-pipe
Code:
#!/bin/bash
VERZEICHNIS=/etc

mkfifo /tmp/testpipe
3<>/tmp/testpipe

find $VERZEICHNIS  | cpio -ovc 2>&3 > /tmp/test.cpio &

while read -t10 -u3 LINE
do
#hier könnte jetzt die Auswertung vorgenommen werden
  echo "es wurde geschrieben vom  Prozess 2  $LINE"
done

rm /tmp/testpipe
rm /tmp/test.cpio
  • Wir sichern in unserem Beispiel /etc in /tmp/test.cpio
  • Es wird eine named pipe /tmp/testpipe angelegt.
  • Danach wird ein neuer File Descriptor 3 zum lesen und schreiben eröffnet und mit der named pipe verbunden
  • find sucht Dateinamen und übergibt sie per pipe an cpio und dort werden die Ausgaben umgeleitet nach /tmp/test.cpio
    Die Ausgabe von STDERR von cpio wird zur named Pipe umgeleitet
    die gesamme Befehlsgruppe geht mit & in den Hintergrund, da sonst der Prozess angehalten wird, wenn nicht aus der named pipe gelesen wird.
  • mit while read lesen wir aus der named pipe bis ein Timeout von 10 Sekunden erfolgt.
  • Ausgabe der gelesenen Zeilen mit Kommentar
  • löschen der named pipe und der cpio Ausgabedatei
robi
 

regexer

Advanced Hacker
robi schrieb:
Hier mal ganz einfaches Beispiel einer Rückkopplung mit named-pipe
Interessant! Ich habe so noch nie mit Descriptoren gearbeitet. Verstehe ich das richtig: ohne Timeout arbeitet die while-read-Kombination endlos. So könnte man permanente Systemprozesse kreieren ...
 
A

Anonymous

Gast
notoxp schrieb:
Verstehe ich das richtig: ohne Timeout arbeitet die while-read-Kombination endlos. So könnte man permanente Systemprozesse kreieren ...

Permanente Systemprozesse werden das nicht, sondern nur Endlosschleifen in Userprozessen die auf Eingaben warten.
Die while read Schleife arbeitet prinzipiell bis ein EOF kommt. Da wir in unserem Beispiel den Standartfehlerkanal über die Pipe jagen und cpio beim Beenden nicht die Pipe schließt, da sie den File Deskriptor geerbt hat und nicht explizit den Kanal schließt, kommt kein EOF , ich muss also damit mein Script beendet wird ein Timeout einbauen.

Musste soeben feststellen dass nicht jede bash Version -u und -t kennt. -u habe ich in Version 2.05 , 2.05a und 2.03 nicht gefunden(gibt es definitiv erst ab 2.05b) und -t habe ich in 2.03 auch nicht gefunden. Also Vorsicht wenn ihr solche scripte schreibt die auf andere Rechner portiert werden sollen.

robi
 
Oben