Ls und Eingabeumleitung

Ls und Eingabeumleitung

Ich möchte den Inhalt einer Datei zur lsBefehlseingabe umleiten:

ls -l < /home/john/1.txt

wo 1.txtder Inhalt nur ist:

/etc

Ich hatte erwartet ls, den Inhalt der in „Datei“ definierten Datei aufzulisten /home/jonh1.txt– also /etc„Dir“, aber der Eingabestrom wird anscheinend ignoriert – es wird trotzdem der Inhalt des aktuellen Verzeichnisses aufgelistet, statt des /etcin /home/jonh1.txtder Datei definierten Verzeichnisses.

Antwort1

es scheint den Eingabestrom zu ignorieren

Ja. Das lsProgrammniemalsverwendet den Eingabestrom, da es nicht dafür geschrieben wurde, etwas aus dem Eingabestrom zu lesen. Dies ist nicht automatisch in jedem Unix-Programm enthalten – es muss separat implementiert werden.

Verwechseln Sie den Eingabestream (stdin) nicht mit den Befehlszeilenargumenten (argv); ersterer ist ein tatsächlicher Stream, der zeilenweise gelesen werden kann, während letzterer ein einfaches schreibgeschütztes Array von Wörtern ist. In Ihrem Fall sind beide vorhanden und enthalten unterschiedliche Daten.

(Warum sollte es nicht automatisch für alle Programme sein? Nun, nehmen SieSortierenoderKatzeodergrepals Beispiel. Diese Programme akzeptieren verschiedene Arten von Werten – Dateinamen als Argumente, aber Text als Standardeingabeinhalt. Sie können also jeden Befehl per Pipe an senden | sortund die Eingabe wird sortiert. Aber wenn Standardeingabe und Befehlszeile dasselbe wären, könnten Sie nichts | sortmehr per Pipe an senden, weil es denken würde, die Pipe-Eingabe wäre eine Liste von Dateinamen. Oder umgekehrt, Sie könnten ihm keine Dateinamen geben, weil es nur die Namen sortieren würde.)

Eine alternative Version finden Sie unterdiese Erklärung auf StackOverflow(was Sie bereits in den Kommentaren erhalten haben).

Antwort2

Versuchen Sie es mit xargs:

xargs ls -l < /home/john/1.txt

Antwort3

Wenn Sie ein Kommandozeilenprogramm schreiben, das Benutzereingaben entgegennimmt, werden Sie sehr deutlich sehen, was passiert. Wenn ein Programm eine read/readLine-Anweisung (in verschiedenen Sprachen wird sie möglicherweise anders genannt) hat, das Programm also den Benutzer zur Eingabe auffordert, können Sie diese Eingabe auch weiterleiten oder umleiten, indem Sie |oder<

Wenn Sie sich ein Programm ansehen, das Eingaben entgegennimmt, sehen Sie etwas wie mit moreoder less. Wenn Sie es ohne Eingabe eingeben $more<ENTER>, fordert es zur Eingabe auf. Indem es Daten weiterleitet, hört es auf, zur Eingabe aufzufordern. Wenn wir sed ohne Parameter ausführen, $sed<ENTER>gibt es natürlich einen Fehler aus, und wir können $echo abc|sed<ENTER>beides nicht tun. Aber wenn wir $sed 's/a/b/'<ENTER>es tun, fordert es zur Eingabe auf. Und deshalb echo abc|sed 's/a/b/'<ENTER> funktioniert es.

Sie können dies sehen, wenn Sie ein Programm schreiben, selbst ein so einfaches wie „Hello World“, das aber Eingaben akzeptiert, wie das Programm, das nach einem Wort fragt, und wenn die Person „abc“ eingibt, wird „Hallo abc“ angezeigt. Sie können eine Weiterleitung zu diesem Programm durchführen. Es ist keine zusätzliche Programmierung erforderlich, um die Weiterleitung und Umleitung von Eingaben zum Laufen zu bringen. Wenn das Programm Tastatureingaben vom Benutzer akzeptiert, funktionieren die Weiterleitung und Umleitung dorthin, und das Programm fordert dann keine Eingaben an.

Antwort4

Bearbeiten

Wie Kamil Maciorowski in einem Kommentar unten anmerkte, ist der folgende Weg nicht der richtige.

Wenn /home/john/1.txtgarantiert genau ein Pfad enthalten ist, dannSie sollten auf jeden Fall doppelte Anführungszeichen setzenWenn die Datei mehr als einen Pfad enthalten kann und Sie bewusst auf die Worttrennung setzen, dann ist dies nicht der richtige Weg, beliebige Pfade anzugeben.

Originalbeitrag (schlechtes Beispiel)

Sie können Folgendes verwenden:

ls -l $(cat /home/john/1.txt)

Siehe > man bashSektionBefehlsersetzung.

verwandte Informationen