Fatmawati Achmad Zaenuri/Shutterstock
Müssen Sie einige Linux-Befehle aneinanderreihen, aber einer von ihnen akzeptiert keine Pipe-Eingabe? xargs
kann die Ausgabe von einem Befehl nehmen und als Parameter an einen anderen Befehl senden.
Alle Standard-Linux-Dienstprogramme haben drei Datenströme mit ihnen verbunden. Dies sind der Standardeingabestrom (stdin), der Standardausgabestrom (stdout) und der Standardfehlerstrom (stderr).
Diese Streams arbeiten mit Text. Wir senden eine Eingabe (stdin) an einen Befehl mit Text, und die Antwort (stdout) wird als Text in das Terminalfenster geschrieben. Fehlermeldungen werden auch als Text (stderr) in das Terminalfenster geschrieben.
Eine der großartigen Eigenschaften von Linux- und Unix-ähnlichen Betriebssystemen ist die Möglichkeit, die stdout-Ausgabe eines Befehls in die stdin-Eingabe eines zweiten Befehls zu leiten. Dem ersten Befehl ist es egal, dass seine Ausgabe nicht an ein Terminalfenster geht, und dem zweiten Befehl ist es egal, dass seine Eingabe nicht von einer Tastatur kommt.
Obwohl alle Linux-Befehle die drei Standard-Streams haben, akzeptieren nicht alle die stdout eines anderen Befehls als Eingabe für ihre stdin. Das bedeutet, dass Sie keine Eingaben an sie weiterleiten können.
xargs
ist ein Befehl zum Erstellen von Ausführungspipelines unter Verwendung der Standarddatenströme. Durch die Nutzung xargs
wir können Befehle machen wie echo
, rm
, und mkdir
akzeptieren Standardeingaben als Argumente.
Der xargs-Befehl
xargs
akzeptiert über Pipe geleitete Eingaben. Es kann auch Eingaben aus einer Datei akzeptieren. xargs
verwendet diese Eingabe als Parameter für die Befehle, mit denen sie arbeiten soll. Wenn wir es nicht sagen xargs
um mit einem bestimmten Befehl zu arbeiten, wird dieser standardmäßig verwendet echo
.
Wir können das verwenden, um zu zeigen, wie xargs
erzeugt immer eine einzelne Ausgabezeile, auch bei mehrzeiligen Eingaben.
Wenn wir die verwenden -1
(eine Datei pro Zeile auflisten) Option mit ls
, wir bekommen ein einzelne Spalte mit Dateinamen.
ls -1 ./*.sh
Dies listet die Shell-Skriptdateien im aktuellen Verzeichnis auf.
Wir erhalten wie erwartet eine einzelne Spalte. Wenn wir es durchleiten xargs
was bekommen wir?
ls -1 ./*.sh | xargs
Die Ausgabe wird als ein langer Textstrom in das Terminalfenster geschrieben.
Es ist diese Fähigkeit, die uns xargs
Parameter in andere Befehle einspeisen.
Verwenden von xargs mit wc
Wir können benutzen xargs
leicht haben wc
zähle die Wörter, Zeichen und Zeilen in mehreren Dateien.
ls *.page | xargs wc
Das ist, was passiert:
ls
listet die *.page-Dateien auf und übergibt die Liste an xargs
.
xargs
übergibt die Dateinamen an wc
.
wc
behandelt die Dateinamen so, als hätte sie sie als Kommandozeilenparameter erhalten.
Die Statistiken für jede Datei werden zusammen mit einer Gesamtsumme angezeigt.
Verwenden von xargs mit Bestätigung
Wir können die nutzen -p
(interaktive) Option zu haben xargs
bitten Sie uns um eine Bestätigung, dass wir damit einverstanden sind, fortzufahren.
Wenn wir eine Zeichenfolge von Dateinamen an . übergeben touch
, durch xargs
, touch
Wille die Dateien erstellen für uns.
echo 'one two three' | xargs -p touch
Der auszuführende Befehl wird angezeigt und xargs
wartet auf unsere Antwort, indem wir „y“ oder „Y“ oder „n“ oder „N“ eingeben und die Eingabetaste drücken.
Wenn Sie nur die Eingabetaste drücken, wird es als „n“ behandelt. Der Befehl wird nur ausgeführt, wenn Sie „y“ oder „Y“ eingeben.
Wir haben «y» gedrückt und Enter gedrückt. Wir können benutzen ls
um zu überprüfen, ob die Dateien erstellt wurden.
ls one two three
Verwenden von xargs mit mehreren Befehlen
Wir können mehrere Befehle mit verwenden xargs
mit der -I
(Anfangsargumente) Option.
Diese Option definiert einen „replace-string“. Überall dort, wo das Token für die Ersetzungszeichenfolge in der Befehlszeile erscheint, werden die Werte, die an . geliefert wurden, angezeigt xargs
eingefügt werden.
Lass uns das benutzen tree
Befehl, um die Unterverzeichnisse des aktuellen Verzeichnisses anzuzeigen. Die -d
(Verzeichnis-)Option Ursachen tree
um Dateien zu ignorieren und nur über Verzeichnisse zu berichten.
tree -d
Es gibt ein einziges Unterverzeichnis namens „images“.
In einer Datei namens „directories.txt“ haben wir die Namen einiger Verzeichnisse, die wir erstellen möchten. Wir können uns den Inhalt ansehen mit cat
.
cat directories.txt
Wir verwenden dies als Eingabedaten für xargs
. Der Befehl, den wir ausführen werden, lautet:
cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'
Das gliedert sich wie folgt auf:
- : Dies schiebt den Inhalt der Dateidirectrories.txt (alle neuen Verzeichnisnamen) in
xargs
.
- : Dies definiert einen „replace-string“ mit dem Token „%“.
- : Dies startet eine neue Subshell. Die
-c
(Befehl) weist die Shell an, Befehle von der Befehlszeile zu lesen.
- : Jedes der „%“-Token wird durch die Verzeichnisnamen ersetzt, die von übergeben werden
xargs
. Die echo
Befehl gibt den Verzeichnisnamen aus; das mkdir
Befehl erstellt das Verzeichnis.
Die Verzeichnisse werden nacheinander aufgelistet.
Wir können benutzen tree
noch einmal, um zu überprüfen, ob die Verzeichnisse erstellt wurden.
tree -d
Kopieren von Dateien an mehrere Speicherorte
Wir können benutzen xargs
um es uns zu ermöglichen, Dateien mit einem einzigen Befehl an mehrere Speicherorte zu kopieren.
Wir werden die Namen von zwei Verzeichnissen in pipen xargs
als Eingabeparameter. Wir werden es sagen xargs
um jeweils nur einen dieser Parameter an den Befehl zu übergeben, mit dem er arbeitet.
In diesem Fall lautet der Befehl cp
. Der Effekt ist also, anzurufen cp
zweimal, jeweils mit einem der beiden Verzeichnisse als Kommandozeilenparameter. Die xargs
Parameter, der dies ermöglicht, ist der -n
(maximale Anzahl) Option. Wir werden dies so einstellen, dass es eins ist.
Wir verwenden auch die -v
(ausführliche) Option mit cp
damit es meldet, was passiert.
echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page
Die Dateien werden nacheinander in die beiden Verzeichnisse kopiert. cp
meldet jede Dateikopieraktion, damit wir sie sehen können.
Löschen von Dateien in verschachtelten Verzeichnissen
Wenn Dateinamen Leerzeichen und seltsame Zeichen enthalten – wie z. B. Zeilenumbruchzeichen – xargs
werden sie nicht richtig interpretieren können. Wir können dieses Problem lösen, indem wir die Option -0 (null terminator) verwenden. Das sagt xargs
um das Nullzeichen als letztes Trennzeichen für Dateinamen zu verwenden.
Wir werden verwenden find
in diesem Beispiel. find
hat seine eigene Option für Umgang mit Leerzeichen und seltsame Zeichen in Dateinamen. Es ist der -print0
(vollständiger Name, Nullzeichen) Option.
find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
Das gliedert sich wie folgt auf:
- :
find
wird im aktuellen Verzeichnis «.» suchen. für Objekte mit Namen, die mit „*.png“ übereinstimmen, die Dateien sind (type -f
).
- : Namen werden mit einem Nullzeichen abgeschlossen und Leerzeichen und seltsame Zeichen werden berücksichtigt.
- : betrachtet Dateinamen auch als nullterminiert, und Leerzeichen und seltsame Zeichen verursachen keine Probleme.
- : rm wird ausführlich sein und berichten, was passiert (
-v
). Es wird rekursiv (-r) sein und verschachtelte Unterverzeichnisse durchsuchen und Dateien ohne Aufforderung entfernen (-f
). Das „{}“ wird durch jeden Dateinamen ersetzt.
Alle Unterverzeichnisse werden durchsucht und die Dateien, die dem Suchmuster entsprechen, werden gelöscht.
Verschachtelte Verzeichnisse entfernen
Nehmen wir an, wir möchten eine Reihe von verschachtelten Unterverzeichnissen entfernen. tree
werden wir sie sehen lassen.
tree -d
find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"
Dieser Befehl verwendet find, um rekursiv im aktuellen Verzeichnis zu suchen. Das Suchziel ist ein Verzeichnis namens „level_one“. Die Verzeichnisnamen werden durchgereicht xargs
zu rm
.
Die einzigen wesentlichen Änderungen zwischen diesem Befehl und dem vorherigen Befehl sind, dass der Suchbegriff der Name des obersten Verzeichnisses ist und -type d
erzählt find
nach Verzeichnissen zu suchen, nicht nach Dateien.
Der Name jedes Verzeichnisses wird gedruckt, wenn es entfernt wird. Wir können überprüfen mit tree
:
tree -d
Alle verschachtelten Unterverzeichnisse werden gelöscht.
Löschen aller Dateien mit Ausnahme eines Dateityps
Wir können benutzen find
, xargs
und rm
um alle Dateien außer einem Typ zu löschen, den wir behalten möchten. Es ist etwas kontraintuitiv, aber wir geben den Namen des Dateityps an, den wir löschen möchten, nicht den Namen derjenigen, die wir löschen möchten.
Die -not
Option sagt find
um die Namen der Dateien zurückzugeben, die dem Suchmuster entsprechen. Wir verwenden die -I
(Anfangsargumente) Option mit xargs
einmal mehr. Dieses Mal ist das Ersetzungszeichenfolge-Token, das wir definieren, „{}“. Dies verhält sich genau so wie das zuvor generierte Token zum Ersetzen der Zeichenfolge, das zufällig ein „%“ war.
find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}
Wir kann mit überprüfen ls
. Die einzigen im Verzeichnis verbleibenden Dateien sind diejenigen, die dem Suchmuster „*.sh“ entsprechen.
ls -l
Erstellen einer Archivdatei mit Xargs
Wir können benutzen find
um nach Dateien zu suchen und sie weiterzugeben xargs
zu tar
, um eine Archivdatei zu erstellen.
Wir suchen im aktuellen Verzeichnis. Das Suchmuster ist „*.page“, also suchen wir nach „.page“-Dateien.
find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz
Die Dateien werden wie erwartet aufgelistet, während die Archivdatei erstellt wird.
Der Datenvermittler
Manchmal braucht man beim Stapeln ein kleines Gerüst. xargs
überbrückt die Lücke zwischen Befehlen, die Informationen ausgeben können, und Befehlen, die nicht dafür ausgelegt sind, sie aufzunehmen.
Beide xargs
und find
haben eine Vielzahl von Möglichkeiten. Sie werden ermutigt, ihre Manpages zu lesen, um mehr zu erfahren.