Multi-threaded xargs met voorbeelden

  • Richard Poole
  • 0
  • 3777
  • 235
>

Als je nieuw bent bij xargs, of weet niet wat xargs is, lees eerst onze xargs voor beginners met voorbeelden. Als je er al een beetje aan gewend bent xargs, en kan basic schrijven xargs command line statements zonder de handleiding te bekijken, dan zal dit artikel je helpen om geavanceerder te worden met xargs op de opdrachtregel, vooral door het multi-threaded te maken.

In deze tutorial leer je:

  • Hoe te gebruiken xargs -P (multi-threaded mode) vanaf de opdrachtregel in Bash
  • Geavanceerde gebruiksvoorbeelden met multi-threaded xargs vanaf de opdrachtregel in Bash
  • Een dieper begrip van hoe toe te passen xargs multi-threaded naar uw bestaande Bash-code
Multi-threaded xargs met voorbeelden

Gebruikte softwarevereisten en -conventies

Softwarevereisten en Linux Command Line-conventies
Categorie Vereisten, conventies of gebruikte softwareversie
Systeem Linux-distributie-onafhankelijk
Software Bash-opdrachtregel, op Linux gebaseerd systeem
Andere De xargs hulpprogramma is standaard opgenomen in de Bash-shell
Conventies # - vereist dat linux-commando's worden uitgevoerd met root-privileges, hetzij direct als rootgebruiker, hetzij door gebruik van sudo opdracht
$ - vereist dat linux-commando's worden uitgevoerd als een gewone niet-geprivilegieerde gebruiker

Voorbeeld 1: Een andere Bash-shell aanroepen met xargs gecompileerde invoer

Nadat men gebruikt heeft om te leren xargs, hij of zij zal dat snel ontdekken - terwijl xargs stelt iemand in staat om veel krachtige dingen zelf te doen - de kracht van xargs lijkt te worden beperkt door het onvermogen om meerdere opdrachten achter elkaar uit te voeren.

Laten we bijvoorbeeld zeggen dat we een map hebben met de naam submappen 00 naar 10 (11 in totaal). En voor elk van deze submappen willen we ernaar bladeren en controleren of een bestand met de naam bestand.txt bestaat, en zo ja kat (en samenvoegen met >>) de inhoud van dit bestand naar een bestand total_file.txt in de directory waar het 00 naar 10 directories zijn. Laten we proberen dit met xargs in verschillende stappen:

$ mkdir 00 01 02 03 04 05 06 07 08 09 10 $ ls 00 01 02 03 04 05 06 07 08 09 10 $ echo 'a'> 03 / file.txt $ echo 'b'> 07 / file.txt $ echo 'c'> 10 / bestand.txt 

Hier maken we eerst 11 mappen aan, 00 naar 10 en maak vervolgens 3 monsters bestand.txt bestanden in de submappen 03, 07 en 10.

$ vinden. -maxdepth 2 -type f -naam bestand.txt ./10/file.txt ./07/file.txt ./03/file.txt 

We schrijven dan een vind commando om alles te lokaliseren bestand.txt bestanden die beginnen bij de huidige directory (.) en dat tot maximaal 1 niveau van submappen:

$ vinden. -maxdepth 2 -type f -naam bestand.txt | xargs -I  cat > ./total_file.txt $ cat total_file.txt c b a 

De -maxdiepte 2 geeft aan de huidige directory (1) en alle submappen van deze map (vandaar de maximale diepte van 2).

Eindelijk gebruiken we xargs (met de aanbevolen en geprefereerde vervangende string zoals doorgegeven aan de xargs -ik vervang string optie) om de inhoud van een dergelijk bestand in de vind commando naar een bestand in de huidige map met de naam total_file.txt.

Iets leuks om hier op te merken is dat, ook al zou men erover nadenken xargs als vervolgens meerdere uitvoeren kat commando's die allemaal naar hetzelfde bestand verwijzen, die men kan gebruiken > (uitvoer naar een nieuw bestand, het bestand aanmaken als het nog niet bestaat en elk bestand met dezelfde naam dat al aanwezig is, overschrijven) in plaats van >> (voeg toe aan een bestand en maak het bestand als het nog niet bestaat)!



De oefening tot nu toe soort van voldeed aan onze vereisten, maar het kwam niet precies overeen met de vereiste - het gaat namelijk niet door de submappen. Het maakte ook geen gebruik van de >> omleiding zoals gespecificeerd, hoewel het in dit geval nog steeds zou hebben gewerkt.

De uitdaging met het uitvoeren van meerdere opdrachten (zoals het specifieke CD commando vereist om van binnenuit de directory te veranderen / naar de subdirectory te bladeren xargs is dat 1) ze erg moeilijk te coderen zijn, en 2) het misschien helemaal niet mogelijk is om dit te coderen.

Er is echter een andere en gemakkelijk te begrijpen manier om dit te coderen, en als u eenmaal weet hoe u dit moet doen, zult u dit waarschijnlijk in overvloed gebruiken. Laten we erin duiken.

$ rm total_file.txt 

We hebben eerst onze vorige uitvoer opgeschoond.

$ ls -d --color = nooit [0-9] [0-9] | xargs -I  echo 'cd ; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi 'cd 00; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 01; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 02; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 03; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 04; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 05; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 06; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 07; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 08; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 09; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi cd 10; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi 

Vervolgens hebben we een commando geformuleerd, dit keer met behulp van ls waarin alle mappen worden weergegeven die overeenkomen met de [0-9] [0-9] reguliere expressie (lees onze Advanced Bash-regex met voorbeeldenartikel voor meer informatie over reguliere expressies).

We gebruikten ook xargs, maar deze keer (in vergelijking met eerdere voorbeelden) met een echo commando dat precies zal uitvoeren wat we zouden willen doen, zelfs als het meer dan een of meer commando's vereist. Beschouw dit als een miniscript.

We gebruiken ook cd om naar mappen te gaan zoals vermeld door de ls -d (alleen mappen) -opdracht (die als een kanttekening wordt beschermd door de --kleur = nooit clausule die kleurcodes in de ls uitvoer van onze resultaten scheef), en controleer of het bestand bestand.txt is er in de submap door een als [-r ... opdracht. Als het bestaat, wij kat de bestand.txt in … /Totaal_bestand.txt. Merk op ... als de cd in het commando heeft ons in de submap geplaatst!

We voeren dit uit om te zien hoe het werkt (tenslotte alleen het echo is geëxecuteerd; er gebeurt eigenlijk niets). De gegenereerde code ziet er geweldig uit. Laten we nu nog een stap verder gaan en daadwerkelijk hetzelfde uitvoeren:

$ ls -d --color = nooit [0-9] [0-9] | xargs -I  echo 'cd ; als [-r ./file.txt]; dan cat file.txt >>… /total_file.txt; fi '| xargs -I  bash -c "" $ cat total_file.txt a b c 


We hebben nu het totale script uitgevoerd met behulp van een specifiek (en altijd hetzelfde, d.w.z. je zult merken dat je schrijft | xargs -I bash -c "" met enige regelmaat) commando, dat alles uitvoert wat werd gegenereerd door de echo eraan voorafgegaan: xargs -I bash -c "". In feite is dit de Bash-interpreter vertellen om uit te voeren wat eraan is doorgegeven - en dit voor elke gegenereerde code. Zeer krachtig!

Voorbeeld 2: xargs met meerdere threads

Hier zullen we twee verschillende bekijken xargs commando's, één uitgevoerd zonder parallelle (multi-threaded) uitvoering, de andere met. Overweeg het verschil tussen de volgende twee voorbeelden:

$ tijd voor i in $ (seq 1 5); echo $ [$ RANDOM% 5 + 1]; gedaan | xargs -I  echo "sleep ; echo 'Klaar! '" | xargs -I  bash -c "" Klaar! 5 Klaar! 5 Klaar! 2 Klaar! 4 Klaar! 1 echte 0m17.016s gebruiker 0m0.017s sys 0m0.003s 
$ tijd voor i in $ (seq 1 5); echo $ [$ RANDOM% 5 + 1]; gedaan | xargs -I  echo "sleep ; echo 'Klaar! '" | xargs -P5 -I  bash -c "" Klaar! 1 Klaar! 3 Klaar! 3 Klaar! 3 Klaar! 5 echte 0m5.019s gebruiker 0m0.036s sys 0m0.015s 

Het verschil tussen de feitelijke twee opdrachtregels is klein; we hebben alleen toegevoegd -P5 in de tweede opdrachtregel. De looptijd echter (zoals gemeten door de tijd command prefix) is significant. Laten we eens kijken waarom (en waarom de output verschilt!).

In het eerste voorbeeld maken we een voor lus die 5 keer wordt uitgevoerd (vanwege de subshell $ (seq 1 5) nummers genereren van 1 naar 5) en daarin echoën we een willekeurig getal tussen 1 en 5. Vervolgens hebben we, veel in lijn met het laatste voorbeeld, deze uitvoer naar het slaapcommando gestuurd en ook de duur van de slaap als onderdeel van de Klaar! echo. Ten slotte hebben we dit verzonden om te worden uitgevoerd door een subshell Bash-commando, opnieuw op dezelfde manier als in ons vorige voorbeeld.

De uitvoer van het eerste commando werkt als volgt; een slaapstand uitvoeren, resultaat uitvoeren, de volgende slaapstand uitvoeren, enzovoort.

Het tweede commando verandert dit echter volledig. Hier hebben we toegevoegd -P5 die in feite 5 parallelle threads in één keer start!

De manier waarop deze opdracht werkt, is: start tot x threads (zoals gedefinieerd door de optie -P) en verwerk ze tegelijkertijd. Als een thread compleet is, pak dan onmiddellijk nieuwe input, wacht niet tot andere threads als eerste klaar zijn. Het laatste deel van die beschrijving is hier niet van toepassing (het zou alleen zijn als er minder threads waren gespecificeerd door -P. dan het aantal 'regels' invoer gegeven, of met andere woorden er zouden minder parallelle threads beschikbaar zijn dan het aantal rijen invoer).

Het resultaat is dat de threads die als eerste eindigen - die met een korte willekeurige slaaptijd - als eerste terugkomen en hun 'Done!' uitspraak. De totale looptijd komt ook terug van ongeveer 17 seconden tot slechts ongeveer 5 seconden precies in echte kloktijd. Stoer!

Gevolgtrekking

Gebruik makend van xargs is een van de meest geavanceerde en ook een van de krachtigste manieren om in Bash te coderen. Maar het stopt niet bij alleen maar gebruiken xargs! In dit artikel hebben we dus multi-threaded parallelle uitvoering via de -P. optie om xargs. We hebben ook gekeken naar het aanroepen van subshells met $ () en tot slot hebben we een methode geïntroduceerd om instructies met meerdere commando's rechtstreeks door te geven aan xargs door een bash -c subshell-oproep.

Krachtig? Wij denken van wel! Laat ons uw mening achter.




Niemand heeft nog op dit artikel gereageerd.

Een verzameling nuttige informatie over het Linux-besturingssysteem en nieuwe technologieën
Nieuwe artikelen, praktische tips, gedetailleerde recensies en handleidingen. Voel je thuis in de wereld van het Linux-besturingssysteem