Per man-Definition erhält dieser Befehl die Eingabe aus einer Datei.
$ command -r FILENAME
Angenommen, es FILENAME
handelt sich um eine Datei mit einer Liste von Dateinamen, wie sie mit generiert wurde ls > FILENAME
.
Wie kann ich stattdessen den Befehl mit dem Ergebnis von ls
direkt füttern ? In meinem Kopf sollte so etwas möglich sein:
$ ls | command -r
Aber es ist nicht der Fall, die Ausgabe von ls
wird nicht als Argument gehakt. Ausgabe:
Usage: command -r FILENAME
error: -r option requires an argument
Wie kann ich den gewünschten Effekt erzielen?
Antworten:
Dies ist befehlsabhängig. Einige Befehle, die aus einer Datei lesen, gehen davon aus, dass es sich bei der Datei um eine reguläre Datei handelt, deren Größe im Voraus bekannt ist und die von jeder Position gelesen und zurückgespult werden kann. Dies ist unwahrscheinlich, wenn der Inhalt der Datei eine Liste von Dateinamen ist: Dann ist der Befehl wahrscheinlich mit einer Pipe zufrieden , die von Anfang bis Ende nacheinander gelesen wird. Es gibt verschiedene Möglichkeiten, Daten über eine Pipe an einen Befehl weiterzuleiten, der einen Dateinamen erwartet.
Viele Befehle werden
-
als spezielle Namen behandelt, dh sie werden von der Standardeingabe gelesen, anstatt eine Datei zu öffnen. Dies ist eine Konvention, keine Verpflichtung.Viele Unix-Varianten enthalten spezielle Dateien
/dev
, die die Standarddeskriptoren bezeichnen. Wenn/dev/stdin
vorhanden, entspricht das Öffnen und Lesen der Datei dem Lesen der Standardeingabe. Ebenso,/dev/fd/0
wenn es existiert.Wenn Ihre Shell ksh, bash oder zsh ist, können Sie die Shell mit der Zuweisung eines Dateideskriptors beauftragen. Der Hauptvorteil dieser Methode besteht darin, dass sie nicht an die Standardeingabe gebunden ist, sodass Sie die Standardeingabe für etwas anderes verwenden und sie mehrmals verwenden können.
Wenn der Befehl erwartet, dass der Name eine bestimmte Form hat (normalerweise eine bestimmte Erweiterung), können Sie versuchen, ihn mit einem symbolischen Link zu täuschen.
Oder Sie können eine Named Pipe verwenden.
Beachten Sie, dass das Generieren einer Liste von Dateien mit
ls
problematisch ist, dals
die Dateinamen in der Regel unleserlich werden, wenn sie nicht druckbare Zeichen enthalten.printf '%s\n' *
ist zuverlässiger - es wird jedes Byte buchstäblich in Dateinamen gedruckt. Dateinamen, die Zeilenumbrüche enthalten, verursachen weiterhin Probleme. Dies ist jedoch unvermeidbar, wenn der Befehl eine Liste von Dateinamen erwartet, die durch Zeilenumbrüche getrennt sind.quelle
Es sollte sein:
Bearbeiten: für Namen mit Leerzeichen:
quelle
command
davon ausgegangen wird, dass alle für die Befehlszeile erforderlichen Dateinamen gleichzeitig vorhanden sind. Einige Versionen von xargs geben jeweilscommand
einige Dateinamen an (10, scheint mir). Sieht aus wie GNU XARGS gibt alles auf einmal.Die einzige zuverlässige Lösung, von der ich weiß, dass sie alle Dateinamen, einschließlich der mit einem Zeilenumbruch, verarbeiten kann, ist:
Das einzige unzulässige Zeichen im Dateinamen ist in diesem Fall das Nullzeichen, das in Dateinamen ohnehin nicht zulässig ist.
quelle
Viele Befehle akzeptieren
-
als "Dateiname", was "Standardeingabe verwenden" bedeutet, aber diese Konvention ist alles andere als universell. Lesen Sie die Manpage.quelle
Dies sollte für Ihren Zweck funktionieren:
ls | command -r /dev/stdin
quelle