Како користити команду каргс на Линуку

Ponekad je potrebno kombinovati više Linux komandi, ali se desi da jedna od njih ne prihvata ulaz putem cevi (pipe)? Komanda xargs može da preuzme izlaz jedne komande i prosledi ga kao argumente drugoj.

Svi standardni Linux alati imaju tri toka podataka koji su povezani sa njima. To su standardni ulazni tok (stdin), standardni izlazni tok (stdout) i standardni tok za greške (stderr).

Ovi tokovi rade sa tekstualnim podacima. Ulaz (stdin) šaljemo komandi u obliku teksta, a odgovor (stdout) se prikazuje u terminalu takođe kao tekst. Poruke o greškama (stderr) se takođe ispisuju u terminalu u tekstualnom obliku.

Jedna od sjajnih karakteristika Linuxa i operativnih sistema sličnih Unix-u je mogućnost prosleđivanja izlaza (stdout) jedne komande kao ulaz (stdin) drugoj. Prvu komandu ne zanima što njen izlaz ne ide u terminal, a drugu ne zanima što njen ulaz ne dolazi sa tastature.

Iako sve Linux komande imaju tri standardna toka, ne prihvataju sve stdout druge komande kao ulaz za svoj stdin. To znači da ne možete proslediti ulaz tim komandama preko cevi.

Komanda xargs služi za konstrukciju cevovoda izvršavanja koristeći standardne tokove podataka. Upotrebom xargs možemo omogućiti da komande poput echo, rm i mkdir prihvataju standardni ulaz kao argumente.

Kako funkcioniše komanda xargs

Komanda xargs prima ulaz kroz cev (pipe) ili iz datoteke. Taj ulaz se koristi kao parametri za komande koje navedemo da se izvrše. Ako ne navedemo komandu sa kojom će xargs raditi, po defaultu će koristiti echo.

Ovim možemo demonstrirati kako će xargs uvek generisati jedan red izlaza, čak i sa višelinijskim ulazom.

Ako koristimo opciju -1 (jedna datoteka po redu) sa komandom ls, dobićemo listu imena datoteka u jednoj koloni.

ls -1 ./*.sh

Ovo prikazuje datoteke shell skripti u trenutnom direktorijumu.

Dobijamo jednu kolonu, kako smo i očekivali. Ako taj izlaz prosledimo kroz xargs, šta ćemo dobiti?

ls -1 ./*.sh | xargs

Izlaz se ispisuje u terminalu kao jedan dugačak tok teksta.

Ova mogućnost omogućava da xargs unosi parametre u druge komande.

Upotreba xargs sa komandom wc

Možemo koristiti xargs da lako nateramo komandu wc da broji reči, karaktere i linije u više datoteka.

ls *.page | xargs wc

Evo šta se dešava:

Komanda ls prikazuje *.page datoteke i prosleđuje listu komandi xargs.
xargs prosleđuje imena datoteka komandi wc.
wc tretira imena datoteka kao da su primljena kao parametri komandne linije.

Statistika za svaku datoteku se prikazuje zajedno sa ukupnim zbirom.

Korišćenje xargs sa potvrdom

Možemo koristiti opciju -p (interaktivno) da xargs traži od nas potvrdu pre nastavka.

Ako prosledimo niz imena datoteka komandi touch, kroz xargs, touch će kreirati datoteke za nas.

echo 'one two three' | xargs -p touch

Prikazuje se komanda koja će biti izvršena i xargs čeka da odgovorimo tako što ćemo ukucati „y“ ili „Y“, ili „n“ ili „N“ i pritisnuti Enter.

Ako samo pritisnete Enter, tretira se kao „n“. Komanda se izvršava samo ako unesete „y“ ili „Y“.

Pritisnuli smo „y“ i pritisnuli Enter. Možemo koristiti ls da proverimo da li su datoteke kreirane.

ls one two three

Korišćenje xargs sa više komandi

Možemo koristiti više komandi sa xargs pomoću opcije -I (inicijalni argumenti).

Ova opcija definiše „string za zamenu“. Gde god se token za zamenu-string pojavi u komandnoj liniji, vrednosti koje su dostavljene u xargs se ubacuju.

Hajde da upotrebimo komandu tree da pogledamo poddirektorijume iz trenutnog direktorijuma. Opcija -d (direktorijum) uzrokuje da tree ignoriše datoteke i izveštava samo o direktorijumima.

tree -d

Postoji jedan poddirektorijum koji se zove „images“.

U datoteci pod nazivom „directories.txt“, imamo imena nekih direktorijuma koje želimo da kreiramo. Možemo pogledati njen sadržaj koristeći cat.

cat directories.txt

Ovo ćemo koristiti kao ulazne podatke za xargs. Komanda koju ćemo uraditi je sledeća:

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

Ovo se raspada ovako:

cat directories.txt |: Ovo prosleđuje sadržaj datoteke directories.txt (sva nova imena direktorijuma) komandi xargs.
xargs -I %: Ovo definiše „string za zamenu“ tokenom %.
sh -c: Ovo pokreće novu podljusku. -c (komanda) govori ljusci da čita komande iz komandne linije.
'echo %; mkdir %': svaki od tokena % će biti zamenjen imenima direktorijuma koje prosleđuje xargs. Komanda echo će ispisati ime direktorijuma; komanda mkdir će kreirati direktorijum.

Imenici su navedeni jedan po jedan.

Možemo još jednom da koristimo tree da proverimo da li su direktorijumi kreirani.

tree -d

Kopiranje datoteka na više lokacija

Možemo koristiti xargs da nam omogući kopiranje datoteka na više lokacija jednom komandom.

Imena dva direktorijuma ćemo proslediti u xargs kao ulazne parametre. Reći ćemo xargs da prosledi samo jedan od ovih parametara u isto vreme komandi sa kojom radi.

U ovom slučaju, komanda je cp. Dakle, efekat je da se cp pozove dva puta, svaki put sa jednim od dva direktorijuma kao parametrom komandne linije. Parametar xargs koji omogućava da se to desi je opcija -n (maksimalni broj). Postavićemo ovo da bude jedan.

Takođe koristimo opciju -v (verbose) sa cp tako da izveštava šta se dešava.

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

Datoteke se kopiraju u dva direktorijuma, jedan po jedan. cp izveštava o svakoj radnji kopiranja datoteke tako da možemo da ih vidimo kako se dešavaju.

Brisanje datoteka u ugneždenim direktorijumima

Ako imena datoteka imaju razmake i čudne znakove u sebi — kao što su znaci novog reda — xargs neće moći da ih protumači ispravno. Taj problem možemo prevazići korišćenjem opcije -0 (null terminator). Ovo govori xargs da koristi null karakter kao konačni graničnik za nazive datoteka.

U ovom primeru ćemo koristiti find. find ima sopstvenu opciju za rešavanje problema sa razmacima i čudnim znakovima u nazivima datoteka. To je opcija -print0 (puno ime, null karakter).

find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"

Ovo se razlaže na sledeći način:

find . -name "*.png": find će pretraživati iz trenutnog direktorijuma "." za objekte sa nazivima koji odgovaraju "*.png" koji su datoteke (-type f).
-print0: imena će biti završena null znakom, a razmaci i čudni znakovi će biti pokriveni.
xargs -0: xargs će takođe smatrati da su nazivi datoteka završeni nulom, a razmaci i čudni znakovi neće uzrokovati probleme.
rm -v -rf "{}": rm će biti opširan i izvestiće šta se dešava (-v). Biće rekurzivan (-r) i pregledaće ugnežđene poddirektorijume i uklanjaće datoteke bez upita (-f). "{}" se zamenjuje svakim imenom datoteke.

Pretražuju se svi poddirektorijumi, a datoteke koje odgovaraju obrascu pretrage se brišu.

Uklanjanje ugneždenih direktorijuma

Recimo da želimo da uklonimo skup ugneždenih poddirektorijuma. tree će nam dozvoliti da ih vidimo.

tree -d

find . -name "level_one" -type d -print0 | xargs -0 rm -v -rf "{}"

Ova komanda će koristiti find za rekurzivnu pretragu unutar trenutnog direktorijuma. Cilj pretrage je direktorijum pod nazivom „level_one“. Imena direktorijuma se prosleđuju kroz xargs u rm.

Jedine značajne promene između ove komande i prethodne komande su, termin za pretragu je ime najvišeg direktorijuma, a -type d kaže find da traži direktorijume, a ne datoteke.

Ime svakog direktorijuma se štampa kako se uklanja. Možemo proveriti pomoću tree:

tree -d

Svi ugnežđeni poddirektorijumi se brišu.

Brisanje svih datoteka, osim jedne vrste datoteke

Možemo koristiti find, xargs i rm da izbrišemo sve datoteke osim jedne vrste koju želimo da zadržimo. Malo je kontraintuitivno, ali mi dajemo naziv tipa datoteke koju želimo da zadržimo, a ne naziv onih koje želimo da izbrišemo.

Opcija -not govori find da vrati imena datoteka koje se ne podudaraju sa obrascem pretrage. Još jednom koristimo opciju -I (inicijalni argumenti) sa xargs. Ovog puta token za zamenu stringa koji definišemo je "{}". Ovo će se ponašati potpuno isto kao i token za zamenu stringa koji smo prethodno generisali, a koji je bio "%".

find . -type f -not -name "*.sh" -print0 | xargs -0 -I {} rm -v {}

Možemo proveriti sa ls. Jedine datoteke koje su ostale u direktorijumu su one koje se poklapaju sa "*.sh" šablonom pretrage.

ls -l

Kreiranje arhivske datoteke sa xargs-om

Možemo koristiti find da tražimo datoteke i prosledimo ih kroz xargs u tar, da kreiramo arhivsku datoteku.

Tražićemo u trenutnom direktorijumu. Obrazac pretrage je "*.page" tako da ćemo tražiti ".page" datoteke.

find ./ -name "*.page" -type f -print0 | xargs -0 tar -cvzf page_files.tar.gz

Datoteke su navedene kako se očekuje, pošto se arhivska datoteka kreira.

Posrednik podataka

Ponekad vam je potreban mali posrednik kada spajate stvari. xargs premošćuje jaz između komandi koje mogu da ispumpaju informacije i komandi koje nisu napravljene da ih prime.

I xargs i find imaju ogroman broj opcija. Preporučujemo da pogledate njihove man stranice da biste saznali više.