
Moet u enkele Linux-opdrachten aan elkaar rijgen, maar een ervan accepteert geen doorgesluisde invoer? xargs kan de uitvoer van het ene commando overnemen en het als parameters naar een ander commando sturen.
Alle standaard Linux-hulpprogramma’s hebben drie datastromen die eraan zijn gekoppeld. Dit zijn de standaardinvoerstroom (stdin), de standaarduitvoerstroom (stdout) en de standaardfoutstroom (stderr).
Deze streams werken met tekst. We sturen input (stdin) naar een commando met behulp van tekst, en het antwoord (stdout) wordt als tekst naar het terminalvenster geschreven. Foutmeldingen worden ook als tekst (stderr) naar het terminalvenster geschreven.
Een van de geweldige eigenschappen van Linux- en Unix-achtige besturingssystemen is de mogelijkheid om de stdout-uitvoer van het ene commando naar de stdin-invoer van een tweede commando te pipen. Het eerste commando geeft er niet om dat de uitvoer niet naar een terminalvenster gaat, en het tweede commando geeft er niet om dat de invoer niet van een toetsenbord komt.
Hoewel alle Linux-commando’s de drie standaardstreams hebben, accepteren ze niet allemaal de stdout van een ander commando als invoer voor hun stdin. Dat betekent dat u geen invoer naar hen kunt doorsluizen.
xargs is een commando voor het bouwen van uitvoeringspijplijnen met behulp van de standaard datastromen. Door het gebruiken van xargs we kunnen commando’s maken zoals echo, rm, en mkdir accepteer standaardinvoer als argumenten.
Het xargs-commando
xargs accepteert doorgesluisde invoer. Het kan ook invoer van een bestand accepteren. xargs gebruikt die invoer als parameters voor de opdrachten die we ermee hebben laten werken. Als we het niet vertellen xargs om te werken met een specifiek commando dat het standaard zal gebruiken echo.
We kunnen dat gebruiken om te laten zien hoe xargs genereert altijd een enkele regel output, zelfs van multi-line input.
Als we de -1 (lijst één bestand per regel) optie met ls, krijgen we een enkele kolom met bestandsnamen.
ls -1 ./*.sh

Dit toont de shell-scriptbestanden in de huidige directory.

We krijgen een enkele kolom zoals verwacht. Als we het erdoorheen leiden xargs wat krijgen we?
ls -1 ./*.sh | xargs

De uitvoer wordt als één lange tekststroom naar het terminalvenster geschreven.

Het is deze mogelijkheid die laten we xargs voer parameters in andere opdrachten in.
Xargs gebruiken met wc
We kunnen gebruiken xargs gemakkelijk te hebben wc tel de woorden, tekens en regels in meerdere bestanden.
ls *.page | xargs wc

Dit is wat er gebeurt:
-
lstoont de * .page-bestanden en geeft de lijst door aanxargs. -
xargsgeeft de bestandsnamen door aanwc. -
wcbehandelt de bestandsnamen alsof het ze heeft ontvangen als opdrachtregelparameters.

De statistieken voor elk bestand worden weergegeven samen met een totaal totaal.
Xargs gebruiken met bevestiging
We kunnen de -p (interactieve) optie om te hebben xargs vraag ons om een bevestiging dat we ermee door willen gaan.
Als we een reeks bestandsnamen doorgeven aan touch, door xargs, touch zal de bestanden voor ons aanmaken.
echo 'one two three' | xargs -p touch

Het commando dat wordt uitgevoerd, wordt weergegeven en xargs wacht op ons antwoord door “y” of “Y”, of “n” of “N” te typen en op Enter te drukken.
Als u gewoon op Enter drukt, wordt het behandeld als “n”. De opdracht wordt alleen uitgevoerd als u “y” of “Y” typt.

We hebben op “y” gedrukt en op Enter gedrukt. We kunnen gebruiken ls om te controleren of de bestanden zijn gemaakt.
ls one two three

Xargs gebruiken met meerdere opdrachten
We kunnen meerdere commando’s gebruiken met xargs door de -I (eerste argumenten) optie.
Deze optie definieert een “vervangtekenreeks”. Overal waar het token voor de replace-string in de opdrachtregel verschijnt, de waarden die zijn opgegeven aan xargs zijn ingevoegd.
Laten we de tree commando om de submappen van de huidige map te bekijken. De -d (directory) optie oorzaken tree om bestanden te negeren en alleen over mappen te rapporteren.
tree -d

Er is een enkele submap met de naam ‘afbeeldingen’.
In een bestand met de naam “directories.txt” hebben we de namen van enkele directories die we willen hebben aangemaakt. We kunnen de inhoud bekijken met cat.
cat directories.txt

We gaan dit gebruiken als de invoergegevens voor xargs. Het commando dat we gaan is dit:
cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'
Dit valt als volgt uiteen:
-
cat directories.txt |: Dit duwt de inhoud van het directrories.txt-bestand (alle nieuwe directorynamen) naar
xargs. - xargs -I%: Dit definieert een “vervang-string” met het token “%”.
-
sh -c: Dit start een nieuwe subshell. De
-c(command) vertelt de shell om commando’s te lezen vanaf de commandoregel. -
‘echo%; mkdir% ‘: elk van de “%” -tokens wordt vervangen door de directory-namen die worden doorgegeven
xargs. Deechocommando zal de mapnaam afdrukken; demkdircommando zal de map aanmaken.

De mappen worden een voor een weergegeven.

We kunnen gebruiken tree nogmaals om te controleren of de mappen zijn gemaakt.
tree -d

Bestanden naar meerdere locaties kopiëren
We kunnen gebruiken xargs zodat we bestanden naar meerdere locaties kunnen kopiëren met een enkele opdracht.
We gaan de namen van twee mappen naar xargs als de invoerparameters. We zullen het vertellen xargs om slechts één van deze parameters tegelijk door te geven aan het commando waarmee het werkt.
In dit geval is de opdracht cp. Dus het effect is om te bellen cp tweemaal, telkens met een van de twee mappen als een opdrachtregelparameter. De xargs parameter die dit mogelijk maakt, is de -n (max aantal) optie. We gaan dit zo instellen.
We gebruiken ook de -v (uitgebreide) optie met cp zodat het rapporteert wat er gebeurt.
echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page

De bestanden worden naar de twee mappen gekopieerd, map voor map. cp rapporteert elke actie voor het kopiëren van bestanden, zodat we ze kunnen zien plaatsvinden.

Bestanden verwijderen in geneste mappen
Als bestandsnamen spaties en vreemde tekens bevatten, zoals tekens voor een nieuwe regel, xargs zal ze niet correct kunnen interpreteren. We kunnen dat probleem oplossen door de optie -0 (null terminator) te gebruiken. Dit vertelt xargs om het null-teken te gebruiken als het laatste scheidingsteken voor bestandsnamen.
We gaan gebruiken find in dit voorbeeld. find heeft zijn eigen optie voor het omgaan met spaties en vreemde tekens in bestandsnamen. Het is de -print0 (volledige naam, nul-teken) optie.
find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
Dit valt als volgt uiteen:
-
vind . -naam “* .png”:
findgaat zoeken in de huidige directory “.” voor objecten met namen die overeenkomen met “* .png” die bestanden zijn (type -f). - -afdruk0: namen worden beëindigd door een nul-teken, en er wordt rekening gehouden met spaties en vreemde tekens.
- xargs -0: xargs gaat ook overwegen bestandsnamen als null-beëindigd te beschouwen, en spaties en vreemde tekens zullen geen problemen veroorzaken.
-
rm -v -rf “{}”: rm wordt uitgebreid en rapporteert wat er gebeurt (
-v). Het wordt recursief (-r) en doorzoekt geneste submappen, en zal bestanden verwijderen zonder te vragen (-f). De “{}” wordt vervangen door elke bestandsnaam.

Alle submappen worden doorzocht en de bestanden die overeenkomen met het zoekpatroon, worden verwijderd.

Geneste mappen verwijderen
Laten we zeggen dat we een set geneste submappen willen verwijderen. tree laat ons ze zien.
tree -d

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"
Deze opdracht gebruikt find om recursief te zoeken in de huidige directory. Het zoekdoel is een directory met de naam “level_one”. De directory-namen worden doorgegeven xargs naar rm.

De enige significante veranderingen tussen dit commando en het vorige commando zijn: de zoekterm is de naam van de bovenste directory, en -type d vertelt find om mappen te zoeken, geen bestanden.

De naam van elke directory wordt afgedrukt zodra deze wordt verwijderd. We kunnen contact opnemen met tree :
tree -d

Alle geneste submappen worden verwijderd.
Alle bestanden verwijderen, behalve één bestandstype
We kunnen gebruiken find, xargs en rm om alle bestanden te verwijderen, behalve één type dat we willen behouden. Het is enigszins contra-intuïtief, maar we geven de naam van het bestandstype dat we willen houden, niet de naam van degene die we willen verwijderen.
De -not optie vertelt find om de namen van de bestanden die niet doen overeenkomen met het zoekpatroon. We gebruiken de -I (eerste argumenten) optie met xargs nog een keer. Deze keer is het vervangende tekenreeks-token dat we definiëren “{}”. Dit gedraagt zich exact hetzelfde als het vervangende tekenreeks-token dat we eerder hebben gegenereerd, wat toevallig een “%” was.
find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}

We kunnen contact opnemen met ls. De enige bestanden die nog in de directory staan, zijn de bestanden die overeenkomen met het zoekpatroon “* .sh”.
ls -l

Een archiefbestand maken met Xargs
We kunnen gebruiken find om naar bestanden te zoeken en ze door te geven xargs naar tar, om een archiefbestand te maken.
We gaan zoeken in de huidige directory. Het zoekpatroon is “* .page”, dus we gaan op zoek naar “.page” -bestanden.
find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz

De bestanden worden weergegeven zoals verwacht, terwijl het archiefbestand wordt gemaakt.

De gegevensbemiddelaar
Soms heb je een steiger nodig als je dingen op elkaar stapelt. xargs overbrugt de kloof tussen opdrachten die informatie kunnen wegpompen en opdrachten die niet zijn gebouwd om deze op te nemen.
Beide xargs en find hebben een groot aantal opties. U wordt aangemoedigd om hun man-pagina’s te bekijken voor meer informatie.