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.