ubuntuusers.de

Wie kontinuierliche Ausgabe auf stdout oder stderr weiterverarbeiten

Status: Ungelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

Sevilo

Anmeldungsdatum:
24. November 2011

Beiträge: Zähle...

Hallo, folgendes Problem möchte ich gern lösen: Eine Anwendung gibt kontinuierlich Daten auf der stdout aus. Diese möchte ich gern in einem Script weiterverarbeiten. Allerdings kenne ich nur die Methode, die bei Aufruf des Scriptes bereits übergebenen n Parameter zu verarbeiten. Nehmen wir als Beispiel "arpwatch". arpwatch gibt auf stdout ständig alle neu registrierten Hosts im Netzwerk aus. Diese Daten würde ich gern mit | an mein Script weitergeben und verarbeiten, weiß aber nicht wie es geht. Die Alternative mit

 arpwatch | nl | zu_verarbeitende_daten.txt 

und dann in einem zweiten Prozess anhand der Zeilennummerierung die jeweils neu hinzugekommenen Daten zu verarbeiten, fände ich sehr unelegant.

ciao

Sevilo

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Du kannst doch in Deinem Script einfach eine while-Schleife mit read kombinieren.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Hi Sevilo,

willkommen erstmal auf dem Forum !

Was ich nicht ganz verstehe, landen die Daten einfach nur auf /dev/stdout (dann brauchst Du ja nur eine Pipe anhängen und fertig) oder schreibst Du sie in eine Datei und möchtest dort den "Zuwachs" beobachten ? (das wäre dann nämlich ein Fall für tail --follow )

Und sonst gibt es da ja auch noch Named Pipes ....

Kannst Du die ganze Sache etwas genauer beschreiben, z.B. was der 1. Prozess wohin ausgibt, und ob der 2. Prozess im Zweifel auch schon vor dem 1. Prozess gestartet werden kann ?

track

Sevilo

(Themenstarter)

Anmeldungsdatum:
24. November 2011

Beiträge: 4

Nein, die Daten landen auf stdout. Das Programm liefert - so lange es läuft - immer neue Daten auf stdout. Diese Daten möchte ich mit einem Script weiterverarbeiten. Nun bin ich mit Scripten noch nicht so vertraut (wie sich ja schon gezeigt hat) und kenne bisher nur die Verarbeitung der beim Aufruf übergebenen n Parameter $1, $2, ..., n$. Dem Hinweis auf read werde ich nachgehen. ciao Sevilo

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Ahso.

Dann wäre das ja wahrscheinlich wirklich nur ein Fall für eine Pipe.
Entweder Du hängst beim Aufruf das Skript mit einer Pipe an Dein komisches Programm an:

arpwatch  |  dein_analyseskript

- dann ist natürlich von der Ausgabe im Terminal nichts mehr zu sehen, nur noch was dein_analyseskript schreibt,
oder Du nimmst den Programmaufruf gleich auch noch mit ins Skript. Dann steht da irgendwo das Programm mit drin, mit einer Pipe dahinter (oder was auch immer).

Hast Du Dich zum Skripten denn schon mal etwas eingelesen, z.B. im Wiki oder bei IBM ?

Und sonst, wenn Du etwas genauer erklärst, wie die Daten aussehen, und was Du da herausziehen willst, können wir Dir sicher auch noch konkretere Hinweise geben. (womöglich fährst Du dann mit sed oder awk besser ?)

track

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

track schrieb:

Dann wäre das ja wahrscheinlich wirklich nur ein Fall für eine Pipe.

Sein Problem war ja nicht die Benutzung einer Pipe, sondern wie er im konsumierenden Script die Ausgabe des anderen kontinuierlich einlesen kann! Daher mein Hinweis mit einer Schleife und read. Ich habe mal was simples zusammen gebastelt:

1
2
3
4
5
6
#!/usr/bin/env bash

while read -r foo
do
    echo "Aus STDOUT: "$foo
done

Testen kann man es z.B. mit ping:

1
2
3
4
5
30 nelson@destiny ~/src/Bash % ping www.google.de | ./pipe_demo.sh
Aus STDOUT: PING www.l.google.com (74.125.43.103) 56(84) bytes of data.
Aus STDOUT: 64 bytes from bw-in-f103.1e100.net (74.125.43.103): icmp_req=1 ttl=55 time=37.7 ms
Aus STDOUT: 64 bytes from bw-in-f103.1e100.net (74.125.43.103): icmp_req=2 ttl=55 time=40.3 ms
Aus STDOUT: 64 bytes from bw-in-f103.1e100.net (74.125.43.103): icmp_req=3 ttl=55 time=37.7 ms

Sevilo

(Themenstarter)

Anmeldungsdatum:
24. November 2011

Beiträge: 4

track schrieb:

Ahso.

Dann wäre das ja wahrscheinlich wirklich nur ein Fall für eine Pipe.

Ja genau, mit der Pipe möchte ich das gern machen. Bisher kenne ich aber nur Übergabe von Daten über n Variablen $1, .., $n, n steht in $# und steht damit wohl schon bei Aufruf fest. Verarbeitung des kontinuierlichen Stroms über die Pipe kenne ich noch nicht.

Entweder Du hängst beim Aufruf das Skript mit einer Pipe an Dein komisches Programm an:

arpwatch  |  dein_analyseskript

- dann ist natürlich von der Ausgabe im Terminal nichts mehr zu sehen,

Wäre nicht so schlimm und ließe sich vielleicht mit

 | tee mein_analysescript

lösen?

Und sonst, wenn Du etwas genauer erklärst, wie die Daten aussehen, und was Du da herausziehen willst, können wir Dir sicher auch noch konkretere Hinweise geben.

Mir geht es erstmal darum, wie ich die Daten von der Pipe in meinem Script entgegennehme. Das Script kann die dann erstmal nach /dev/null, zurück auf stdout oder sonstwohin schicken. Auswertung kommt im nächsten Schritt.

Sevilo

(Themenstarter)

Anmeldungsdatum:
24. November 2011

Beiträge: 4

Lysander schrieb:

track schrieb:

Dann wäre das ja wahrscheinlich wirklich nur ein Fall für eine Pipe.

Sein Problem war ja nicht die Benutzung einer Pipe, sondern wie er im konsumierenden Script die Ausgabe des anderen kontinuierlich einlesen kann! Daher mein Hinweis mit einer Schleife und read. Ich habe mal was simples zusammen gebastelt:

1
2
3
4
5
6
#!/usr/bin/env bash

while read -r foo
do
    echo "Aus STDOUT: "$foo
done

Testen kann man es z.B. mit ping:

1
2
3
4
5
30 nelson@destiny ~/src/Bash % ping www.google.de | ./pipe_demo.sh
Aus STDOUT: PING www.l.google.com (74.125.43.103) 56(84) bytes of data.
Aus STDOUT: 64 bytes from bw-in-f103.1e100.net (74.125.43.103): icmp_req=1 ttl=55 time=37.7 ms
Aus STDOUT: 64 bytes from bw-in-f103.1e100.net (74.125.43.103): icmp_req=2 ttl=55 time=40.3 ms
Aus STDOUT: 64 bytes from bw-in-f103.1e100.net (74.125.43.103): icmp_req=3 ttl=55 time=37.7 ms

Cool, genau das ist es!

merci

Sevilo

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Ja, das ist eine Möglichkeit. Es kommt eben drauf an, was Du willst.
Wenn Du z.B. nur Achten in der Ausgabe finden willst, dann würde schon ein Mini-sed-Skript reichen:

ping google.com  |  sed '/8/ {s/^/Ne Acht, ne Acht: __/; s/8/8(Acht)/'

Wenn es wirklich um des filtern von zeilenweisem Text geht (im weistesten Sinne), da ist ein Shell-Skript eigentlich nur ein Behelf.
Eigentlich sind dafür sed und (für Komplexeres) awk gemacht. Darum dieser Hinweis.

LG,

track

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17625

Wohnort: Berlin

Sevilo schrieb:

Die Alternative mit

 arpwatch | nl | zu_verarbeitende_daten.txt 

und dann in einem zweiten Prozess anhand der Zeilennummerierung die jeweils neu hinzugekommenen Daten zu verarbeiten, fände ich sehr unelegant.

a) Wieso? b) Müßte es aber doch

 arpwatch | nl > zu_verarbeitende_daten.txt 

heißen.

Antworten |