Xargs
xargs – polecenie uniksowych i większości uniksopodobnych systemów operacyjnych, używane do budowania i wykonywania poleceń ze standardowego wejścia. Jądro Linuxa o wersji do 2.6.23 nie może pobierać dowolnie długiej listy argumentów[1], więc zadaniem xargs jest podzielenie jej na wystarczająco małe podlisty.
Na przykład polecenie:
rm /path/*
lub
rm `find /path -type f`
może spowodować błąd i wyświetlenie komunikatu: "Argument list too long" jeżeli w /path znajduje się zbyt wiele plików. Jednakże poniższa wersja (odpowiednik rm `find /path -type f`) nie powinna już sprawiać kłopotów:
find /path -type f -print0 | xargs -0 rm
W tym przykładzie, find przesyła na wejście xargs długą listę nazw plików. Xargs dokonuje podziału na podlisty i dopiero wtedy wywołuje polecenie rm dla każdej z nich. To polecenie jest wydajniejsze niż gdybyśmy chcieli napisać:
find /path -type f -exec rm '{}' \;
co spowoduje wywołanie rm dla każdego, pojedynczego pliku. Warto jednak zwrócić uwagę na to, że w nowszych wersjach find poniższy wariant wykonuje dokładnie to samo, co wersja z użyciem xargs:
find /path -type f -exec rm '{}' +
xargs często wykazuje się takim samym działaniem, jak backquote, lecz jest on bardziej uniwersalny i okazuje się bezpieczniejszym gdy na wejściu pojawiają się znaki białe lub specjalne. Dobrze łączyć go z poleceniami zwracającymi długie listy plików, jak chociażby find, locate, czy grep. Musimy jednak pamiętać wtedy o parametrze -0, jako że bez niego xargs nie radzi sobie najlepiej z nazwami zawierającymi ', " i spacje.
Przykłady
find . -name "*.foo" | xargs grep bar
Równoznaczne z:
grep bar `find . -name "*.foo"`
Zauważ, że powyższa komenda korzysta z odwróconych apostrofów (`) zamiast zwykłych ('). Jej zadaniem jest odnalezienie wszystkich plików o rozszerzeniu .foo, zawierających słowo bar, położonych w bieżącym folderze oraz w jego podkatalogach. Żadne z tych poleceń nie zadziała, jeżeli wśród nazw plików znajdują się białe znaki. Możemy rozwiązać ten problem wpisując:
find . -name "*.foo" -print0 | xargs -0 grep bar
W ten sposób możemy wyodrębnić nazwy plików, rozwiązując tym samym problem z białymi znakami;
find . -name "*.foo" -print0 | xargs -0 -t -r vi
Polecenie to przypomina poprzednie, jednakowoż uruchamia ono edytor vi dla każdego z plików. Flaga -t powoduje wypisanie komendy do strumienia stderr przed przystąpieniem do jej realizacji. -r jest rozszerzeniem GNU informującym, że xargs nie wykona polecenia jeżeli nie otrzyma nic na wejście.
find . -name "*.foo" -print0 | xargs -0 -I {} mv {} /tmp/trash
Powyższa komenda korzysta z -I aby rozkazać xargs wypełnienie {} listą argumentów. Pamiętaj jednak, że nie wszystkie wersje xargs wspomagają składnię {}. W takim wypadku możesz napisać np:
find . -name "*.foo" -print0 | xargs -0 -I xxx mv xxx /tmp/trash
Powyższe polecenie wykorzystuje xxx zamiast {} jako znacznik listy argumentów.
find . -maxdepth 1 -type f -name "*.ogg" -print0 | xargs -0 -r cp -v -p --target-directory=/home/media
To polecenie to nic innego jak:
cp -v -p *.ogg /home/media
lecz nie zajmuje ono tak wielu zasobów, kosztem niezwracania błędu kiedy polecenie cp otrzyma więcej plików niż może obsłużyć. Innym sposobem (w którym to sami decydujemy, gdzie umieścimy argumenty) to:
find . -maxdepth 1 -type f -name "*.ogg" -print0 | xargs -0 -IMYFILES cp MYFILES /home/media
Znak -I w powyższej linii poleceń informuje xargs o tym z którego słowa zastępczego chcesz skorzystać (w przeciwnym wypadku doda argumenty na końcu komendy). Oprócz tego możesz użyć atrybutu -L w celu ograniczenia liczby argumentów. Wtedy polecenie będzie uruchamiane ponownie, aż do wyczerpania listy argumentów. Zaś użycie -L1 spowoduje uruchomienie programu tylko raz dla każdego z zadanych argumentów.
Problem separatorów
Wiele uniksowych narzędzi jest zorientowanych liniowo. Będą one więc działać z xargs tak długo, jak linie nie zawierają ', " lub spacji. Część uniksowych narzędzi może użyć znaku NUL jako separatora (np. perl (wymaga -0 i \0 zamiast \n), locate (wymaga użycia -0), find (wymaga użycia -print0), grep (potrzebuje -z lub -Z), sort (wymaga użycia -z)). Umieszczenie -0 po xargs rozwiązuje problem, lecz wiele innych narzędzi nie może używać znaku NUL jako separatora, np. head, tail, ls, echo, sed, tar, wc, which.
Ludzie często o tym zapominają i uznają, że xargs jest także zorientowany liniowo[2].
Poniżej zilustrowano problem separatorów:
touch 'wazny_plik'
touch 'mniej wazny_plik'
ls mniej* | xargs rm
mkdir -p '12" records'
ls | xargs rmdir
Wykonanie poleceń spowoduje usunięcie wazny_plik i pozostawi katalog 12" records oraz plik o nazwie mniej wazny_plik nietknięte.
GNU Parallel jest zorientowanym liniowo odpowiednikiem Xargs, co umożliwia wykonanie powyższych zadań przy jego pomocy[3].
Przypisy
Linki zewnętrzne
xargs(1)– strona podręcznika systemu Linuxxargs(1): konstruowanie listy argumentów i używanie narzędzia – strona podręcznika systemu FreeBSDxargs(1): konstruowanie listy argumentów i używanie narzędzia – strona podręcznika systemu Linuxxargs(1): konstruowanie listy argumentów i używanie narzędzia – strona podręcznika systemu OpenBSDxargs(1): konstruowanie listy argumentów i wywoływanie narzędzia – strona podręcznika systemu Linux
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.