2009-12-13 6 views
20

Ich bin ziemlich verwirrt auf diese. Brauchen Sie einige Klarstellungen.Verständnis der UNIX-Befehl xargs

Beispiel 1:

pgrep string | xargs ps 

Beispiel 2:

find . | xargs grep whatever 

aus Beispiel 1, ich habe es sammeln ist so:

Suche nach einem "string", das ist Teil des Namens des laufenden Prozesses und Rückgabe der Prozess-IDs aller Übereinstimmungen an 'xargs ps' -> die gerade anhängen ps sich auf die Spiele (die Prozess-IDs selbst sind) zu bekommen die gleiche Ausgabe wie:

ps <processid> 

Kann jemand erklären, was xargs wirklich tut in diesem Fall?

aus Beispiel 2, entnehme ich, es ist so:

Es ist für einige „string“ aus dem aktuellen Arbeitsverzeichnis rekursiv zu suchen. Hier, wie genau funktionieren 'Xargs'?

Ich war der Meinung, dass 'xargs' wiederholt Daten von der Standardeingabe an das 'Argument' an Xargs hängt (das normalerweise ein UNIX-Befehl ist).

Von xargs() man-Seite:

xargs liest Elemente aus der Standardeingabe, durch Leerzeichen voneinander getrennt oder Zeilenumbrüchen (die mit Doppel- oder Einzel Anführungszeichen oder einem Backslash geschützt werden kann), und führt die Befehl (Standard ist/bin/echo) einmal oder mehrmals mit einem beliebigen Initialargument, gefolgt von Elementen, die von der Standardeingabe gelesen werden. Leerzeilen auf der Standardeingabe werden ignoriert.

+0

xargs wirkt wie der "Befehl subtitution" (zumindest mit Bash) erhalten. Es verwandelt Multiline-Ergebnisse (vertikal) in eine einzeilige Liste von Token-Argumenten (horizontal). (Beachten Sie, dass Sie die Ergebnisse ein wenig filtern können (mit sed für ex), bevor Sie sie durch xargs weiterleiten). Plus xargs behandelt den Fehler «_too man arguments_», der vor dem Linux-Kernel 2.6.23 auftreten kann (Siehe [wikipedia] (https://en.wikipedia.org/wiki/Xargs)). Hier ist [ein weiterer hilfreicher Thread] (http://unix.stackexchange.com/questions/24954/when-is-xargs-needed) – Stphane

Antwort

37

Im Allgemeinen xargs ist wie diese

prog verwendet | Xargs Dienstprogramm

wo prog zur Ausgabe einer oder mehr Zeilen/Leerzeichen getrennt Ergebnisse erwartet wird. Der Trick ist, dass xargs nicht tut! nessarly Anruf Dienstprogramm einmal für jedes Ergebnis, stattdessen es teilt die Ergebnisliste in Unterlisten und Anrufe Dienstprogramm für jede Unterliste. Wenn Sie XARGs erzwingen möchten, Dienstprogramm für jedes einzelne Ergebnis aufzurufen, müssen Sie es mit xargs -L1 aufrufen.

Beachten Sie, dass xargs Sie verspricht, dass die Teilliste Dienstprogramm gesendet kürzer als ARG_MAX (dies ist, wie es jene gefürchteten Argument Liste zu lange Fehler vermeidet).Sie können den aktuellen Wert von ARG_MAX mit getconf ARG_MAX

+1

Nun, das ist etwas, mit dem ich mich identifizieren konnte, aber jetzt ist es viel verwirrender geworden. Ich kenne den Grund, warum Xargs da ist, aber es wird gewunden, wenn ich sehe, dass es für mehr als einen Zweck (auf unterschiedliche Weise) verwendet wird. – halluc1nati0n

+7

Betrachten Sie diesen Befehl "finden/etc -type d -depth 1 | xargs echo" die alle Verzeichnisse im Ordner/etc (aber nicht ihre Unterverzeichnisse) ausgibt. Da Echo mehrere Argumente benötigt, ist das Ergebnis eine lange Zeile "/ etc/dir1/etc/dir2 ...". Wenn Sie stattdessen "find/etc -type d -depth 1 | xargs -L1 echo" aufrufen, wird echo für jedes Ergebnis einmal aufgerufen, was dazu führt, dass jedes Verzeichnis von/etc in einer eigenen Zeile gedruckt wird. –

+0

Wie gebe ich Befehle oder Optionen an das Dienstprogramm weiter? Sagen wir, ich möchte uglifyjs ausführen und einen Ordner für die Eingabe in xargs angeben und ausgeben. http://stackoverflow.com/questions/43149786/how-to-process-files-in-nested-directories – Costa

2

xargs wird in der Regel zu einer Gruppe Argumenten zusammen verwendet, so dass Sie einen Fehler „zu viele Argumente“ nicht bekommen, die, wenn Sie eine große Anzahl von Argumenten zu einem

Befehl übergeben tritt in
6
$ echo 'line1 
> line2 
> line3 
> ... 
> lineN ' | xargs cmd1 -a -b 

führen wird:

$ cmd1 -a -b line1 line2 line3 ... lineN 

xargs wird cmd1 ... in mehrere Ausführungen von cmd1 brechen, wenn die Zeilenzahl zu groß wird.

xargs kann für viele andere Aufgaben im Zusammenhang mit der Übergabe von stdin Zeilen als Positionsargumente verwendet werden. Werfen Sie einen Blick auf die Option -P in xargs(1), um mehrere Instanzen eines Befehls parallel auszuführen.

1
#!/bin/sh 
#script to echo out the arguments 1 at a time! 
for a in $* 
do 
    echo $a 
done 

der Befehl

$sh myscript 1 2 3 4 5 

nachgeben

1 
2 
3 
4 
5 

aber

$sh myscript 1 2 3 4 5 6 7 8 9 10 11 

nicht, da die maximale Anzahl von Parametern arbeiten überschritten wird (im nicht wirklich sicher, was das Maximum ist, aber sagen wir mal seine 10 für dieses Beispiel!)

Um dies zu umgehen wir

#!/bin/sh 
#script to echo out the arguments 1 at a time! 
for a in $* 
do 
    echo $a | xargs echo 
done 

dann könnten wir es wie dieses

$sh myscript "1 2 3 4 5" "6 7 8 9 10 11" 

und bekommen das richtige Ergebnis führen, da es nur zwei Parameter sind

+2

Ich weiß nicht, was das Maximum ist, aber es ist definitiv nicht 10. Und Sie können verwenden $ @ anstelle von $ *. Dies ist kein sehr gutes Beispiel dafür, wie man xargs – ghostdog74

9
verwenden könnte

Ein gutes Beispiel für das, was xargs tut, ist zu versuchen, sortierte Prüfsummen für jede Datei in einem Verzeichnis mit find zu bekommen.

find . | cksum | sort 

gibt nur eine Prüfsumme zurück, und es ist nicht klar, wofür die Prüfsumme ist. Nicht was wir wollen. Die Pipe sendet das stdout von find in stdin für cksum. Was cksum wirklich will, ist eine Liste von Befehlszeilenargumenten, z.B.

cksum file001.blah file002.blah file003.blah 

meldet drei Zeilen, eine pro Datei, mit den gewünschten Prüfsummen. Xargs macht den Zaubertrick - konvertiert stdout des vorherigen Programms in eine temporäre und versteckte Befehlszeile, um zum nächsten zu füttern. Die folgende Befehlszeile lautet:

find . | xargs cksum | sort 

Hinweis keine Pipe zwischen Xargs und cksum.

+1

btw, das ist der Hauptbestandteil in meinem Rezept zum Auffinden von doppelten Dateien in zwei oder mehr Verzeichnisse, auch wenn ihre Namen unterschiedlich sind. – DarenW

+0

danke für Einsicht und das Hinzufügen von ausführlichen zu xargs gibt Befehl in Aktion. finden . | xargs --verbose cksum | sort – kumar