staging.inyokaproject.org

Verständnißprobleme mit der |

Status: Gelöst | Ubuntu-Version: Ubuntu 18.04 (Bionic Beaver)
Antworten |

getit

Anmeldungsdatum:
18. Juli 2009

Beiträge: Zähle...

Hallo,

sicher kein fortgeschrittenes Thema, aber ich denke das ist trotzdem der Beste Ort für meine Frage.

Im Kofler steht: Zur Formulierung einer Pipe eignen sich nur solche Kommandos, die die zu verarbeitenden Kommandos aus dem Standardeingabekanal lesen.
(mit diesem Beispiel $ ls -l | less)

Dann folgt ein paar Seiten später folgendes Beispiel zur Kommandosubstitution:
$ ls -lgo $(find /usr/share -name '*README*')
Und der Zusatz: Dieses Ergebnis wäre durch eine einfache Pipe mit dem |-Zeichen nicht möglich. ls erwartet keine Eingaben über die Standardeingabe....

Hä?? Wiederspricht sich das nicht? Kann mir das mal bitte jemand für Dummies erklären - danke.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Mit dem Pipe Operator | leitest du die Ausgabe eines Programms auf stdout links von der Pipe an stdin des Programms rechts von der Pipe weiter. Zu den Kanälen der Shell siehe z.B. Shell/Umleitungen.

less akzeptiert Eingaben auf stdin, ls nicht.

Daher ist es kein Problem die Ausgabe von ls auf die Eingabe von less weiterzuleiten:

ls -l | less 

ls hingegen ignoriert die Eingabe auf stdin und akzeptiert nur Argumente, daher der Weg über die Command Substitution $(befehl), die dafür sorgt, dass das Konstrukt durch die Ausgabe des Befehls auf stdout ersetzt wird. In dem von dir gezeigten Beispiel werden dadurch die gefunden Dateien mit README im Namen als Argumente an ls übergeben.

getit

(Themenstarter)

Anmeldungsdatum:
18. Juli 2009

Beiträge: 7

Danke

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

getit schrieb:

$ ls -lgo $(find /usr/share -name '*README*')

Andere Anmerkungen: das ist ein schlechter Weg dieses Problem zu lösen, weil Dateinamen mit Leerzeichen nicht sauber behandelt werden. Außerdem kann der find auch Verzeichnisse finden und dann sollte man beim ls die Option "-d" verwenden, weil sonst der komplette Verzeichnisinhalt gelistet wird. (Kann natürlich auch sein, dass das gewünscht ist - meist eher nicht, wenn mit find gesucht wird, würde ich sagen.

Andere Lösungsmöglichkeiten sind

1
2
find /usr/share -name '*README*' -exec ls -lgod {} +
find /usr/share -name '*README*' -print0 | xargs -r0 ls -lgod

Wie man sieht, kann man auch eine Pipe unterbringen, wenn man will. 😉 In diesem Fall liest xargs die Argumente von Stdin und gibt sie an ls als Kommandozeilenargumente weiter.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Wenn damit alle Unklarheiten beseitig sind, markiere das Thema bitte noch als gelöst.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

rklm schrieb:

getit schrieb:

$ ls -lgo $(find /usr/share -name '*README*')

Andere Anmerkungen: das ist ein schlechter Weg dieses Problem zu lösen, weil Dateinamen mit Leerzeichen nicht sauber behandelt werden. Außerdem kann der find auch Verzeichnisse finden und dann sollte man beim ls die Option "-d" verwenden, weil sonst der komplette Verzeichnisinhalt gelistet wird. (Kann natürlich auch sein, dass das gewünscht ist - meist eher nicht, wenn mit find gesucht wird, würde ich sagen.

1
2
> find /usr/share -type d -name '*README*'
>

Ich würde sagen, dass es kein solches Verzeichnis gibt. ☺

Antworten |