Hoe de xargs-opdracht op Linux te gebruiken

Een Linux-terminalprompt op een laptop
Fatmawati Achmad Zaenuri / Shutterstock

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

v in een terminalvenster

Dit toont de shell-scriptbestanden in de huidige directory.

uitvoer van ls in een terminalvenster

We krijgen een enkele kolom zoals verwacht. Als we het erdoorheen leiden xargs wat krijgen we?

ls -1 ./*.sh | xargs

ls -1 ./*.sh |  xargs in een terminalvenster

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

ls door xargs geleid in een terminalvenster

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

ls * .pagina |  xargs wc in een terminalvenster

Dit is wat er gebeurt:

  • ls toont de * .page-bestanden en geeft de lijst door aan xargs.
  • xargs geeft de bestandsnamen door aan wc.
  • wc behandelt de bestandsnamen alsof het ze heeft ontvangen als opdrachtregelparameters.

wc-uitvoer in een terminalvenster

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

echo 'een twee drie' |  xargs -p touch in een terminalvenster

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.

xargs vraagt ​​om bevestiging in een terminalvenster

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

uitvoer van ls in een terminalvenster

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

tree -d in een terminalvenster

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

cat directories.txt in een terminalvenster

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. De echo commando zal de mapnaam afdrukken; de mkdir commando zal de map aanmaken.

cat directories.txt |  xargs -I% sh -c 'echo%;  mkdir% 'in een terminalvenster

De mappen worden een voor een weergegeven.

uitvoer van xargs in een terminalvenster

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

tree -d

uitvoer van de boom in een terminalvenster

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

echo ~ / Backups / ~ / Documents / page-files / |  xargs -n 1 cp -v ./*.page in een terminalvenster

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.

uitvoer van xargs en cp in een terminalvenster

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”: find gaat 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.

vind .  -naam "* .png" -type f -print0 |  xargs -0 rm -v -rf "{}" in een terminalvenster

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

Uitvoer van rm in een terminalvenster

Geneste mappen verwijderen

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

tree -d

tree -d in een terminalvenster

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.

vind .  -naam "level_one" -type d printo |  xargs -o rm -v -rf "{}" in een terminalvenster

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.

uitvoer van find en xargs en rm in een terminalvenster

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

tree -d

tree -d in een terminalvenster

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 {}

vind .  -type f -niet - naam "* .sh" -print0 |  xargs -0 -I {} rm -v {} in een terminalvenster

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

uitvoer van ls in een terminalvenster

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

vind ./ - naam "* .pagina" -type f -print0 |  xargs -0 -tar -cvzf page_files.tar.gz in een terminalvenster

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

uitvoer van tar in een terminalvenster

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.

Nieuwste artikelen

Gerelateerde artikelen