Jak korzystać z polecenia xargs w systemie Linux

Potrzebujesz połączyć kilka poleceń Linuksa, ale jedno z nich nie akceptuje wejścia potokowego? xargs może pobrać dane wyjściowe z jednego polecenia i wysłać je do innego polecenia jako parametry.

Wszystkie standardowe narzędzia Linuksa mają trzy strumienie danych związane z nimi. Są to standardowy strumień wejściowy (stdin), standardowy strumień wyjściowy (stdout) i standardowy strumień błędów (stderr).

Te strumienie działają z tekstem. Wysyłamy dane wejściowe (stdin) do polecenia za pomocą tekstu, a odpowiedź (stdout) jest zapisywana w oknie terminala jako tekst. Komunikaty o błędach są również zapisywane w oknie terminala jako tekst (stderr).

Jedną z najlepszych cech systemów operacyjnych Linux i uniksopodobnych jest możliwość przesyłania danych wyjściowych z jednego polecenia potokiem do wejścia stdin drugiego polecenia. Pierwsze polecenie nie dba o to, że jego wyjście nie trafia do okna terminala, a drugie polecenie nie dba o to, że jego wejście nie pochodzi z klawiatury.

Chociaż wszystkie polecenia Linuksa mają trzy standardowe strumienie, nie wszystkie z nich akceptują standardowe wyjście innego polecenia jako dane wejściowe do ich standardowego wejścia. Oznacza to, że nie możesz przesłać do nich danych wejściowych.

xargs to polecenie do tworzenia potoków wykonawczych przy użyciu standardowych strumieni danych. Używając xargs, możemy sprawić, że polecenia takie jak echo, rm i mkdir będą akceptować standardowe wejście jako argumenty.

Komenda xargs

xargs zaakceptuje wejście potokowe. Może również akceptować dane wejściowe z pliku. xargs używa tego wejścia jako parametrów dla poleceń, z którymi ma pracować. Jeśli nie powiemy xargs, aby pracował z określonym poleceniem, domyślnie użyje echo.

Możemy to wykorzystać, aby zademonstrować, jak xargs zawsze generuje pojedynczą linię wyjścia, nawet z wejścia wieloliniowego.

Jeśli użyjemy opcji -1 (wyświetl jeden plik w wierszu) z ls, otrzymamy plik pojedyncza kolumna nazw plików.

ls -1 ./*.sh

v w oknie terminala

Wyświetla listę plików skryptów powłoki w bieżącym katalogu.

wyjście ls w oknie terminala

Otrzymujemy jedną kolumnę zgodnie z oczekiwaniami. Jeśli przepuścimy to przez xargs, co otrzymamy?

ls -1 ./*.sh | xargs

ls -1 ./*.sh |  xargs w oknie terminala

Dane wyjściowe są zapisywane w oknie terminala jako jeden długi strumień tekstu.

ls przesyłane przez xargs w oknie terminala

Jest to funkcja, która pozwala xargs podawać parametry do innych poleceń.

Korzystanie z xargs z wc

Możemy użyć xargs, aby łatwo policzyć wc słowa, znaki i linie w wielu plikach.

ls *.page | xargs wc

ls * .page |  xargs wc w oknie terminala

Oto co się dzieje:

ls wyświetla listę plików * .page i przekazuje ją do xargs.
xargs przekazuje nazwy plików do wc.
wc traktuje nazwy plików tak, jakby otrzymały je jako parametry wiersza poleceń.

wyjście wc w oknie terminala

Statystyki dla każdego pliku są wyświetlane razem z łączną liczbą.

Korzystanie z xargs z potwierdzeniem

Możemy użyć opcji -p (interaktywna), aby xargs poprosił nas o potwierdzenie, że jesteśmy zadowoleni z kontynuacji.

Jeśli przekażemy ciąg nazw plików do dotknięcia, przez xargs, touch will utwórz pliki dla nas.

echo 'one two three' | xargs -p touch

echo 'jeden, dwa, trzy' |  xargs -p dotknij w oknie terminala

Wyświetlane jest polecenie, które ma zostać wykonane, a xargs czeka, aż odpowiemy, wpisując „y” lub „Y”, „n” lub „N” i naciskając klawisz Enter.

Jeśli po prostu naciśniesz Enter, zostanie potraktowane jako „n”. Polecenie jest wykonywane tylko wtedy, gdy wpiszesz „y” lub „Y”.

xargs prosi o potwierdzenie w oknie terminala

Nacisnęliśmy „y” i wcisnęliśmy Enter. Możemy użyć ls, aby sprawdzić, czy pliki zostały utworzone.

ls one two three

wyjście ls w oknie terminala

Używanie xargs z wieloma poleceniami

Możemy używać wielu poleceń z xargs, używając opcji -I (początkowe argumenty).

Ta opcja definiuje „ciąg zastępujący”. Wszędzie tam, gdzie w wierszu poleceń pojawi się token łańcucha zastępczego, wstawiane są wartości, które zostały dostarczone do xargs.

Użyjmy polecenia tree, aby spojrzeć na podkatalogi z bieżącego katalogu. Opcja -d (katalog) powoduje, że drzewo ignoruje pliki i raportuje tylko o katalogach.

tree -d

drzewo -d w oknie terminala

Istnieje jeden podkatalog o nazwie „obrazy”.

W pliku o nazwie „directories.txt” mamy nazwy niektórych katalogów, które chcielibyśmy utworzyć. Na jego zawartość możemy spojrzeć za pomocą cat.

cat directories.txt

cat directories.txt w oknie terminala

Użyjemy tego jako danych wejściowych dla xargs. Polecenie, które zamierzamy wykonać, jest takie:

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

To rozpada się w ten sposób:

cat directories.txt |: Wypycha zawartość pliku directrories.txt (wszystkie nowe nazwy katalogów) do xargs.
xargs -I%: definiuje „ciąg zastępujący” z tokenem „%”.
sh -c: To rozpoczyna nową podpowłokę. -C (polecenie) mówi powłoce, aby czytała polecenia z wiersza poleceń.
’Echo %; mkdir% ’: każdy z tokenów „%” zostanie zastąpiony nazwami katalogów przekazanymi przez xargs. Polecenie echo wydrukuje nazwę katalogu; komenda mkdir utworzy katalog.

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

Katalogi są wymienione jeden po drugim.

wyjście xargs w oknie terminala

Możemy ponownie użyć drzewa, aby sprawdzić, czy katalogi zostały utworzone.

tree -d

wyjście z drzewa w oknie terminala

Kopiowanie plików do wielu lokalizacji

Możemy użyć xargs, aby umożliwić nam kopiowanie plików do wielu lokalizacji za pomocą jednego polecenia.

Zamierzamy potokować nazwy dwóch katalogów do xargs jako parametry wejściowe. Powiemy xargs, aby przekazywał tylko jeden z tych parametrów na raz do polecenia, z którym pracuje.

W tym przypadku polecenie to cp. Efektem jest więc dwukrotne wywołanie cp, za każdym razem z jednym z dwóch katalogów jako parametrem wiersza poleceń. Parametr xargs, który na to pozwala, to opcja -n (maksymalna liczba). Ustawimy to jako jeden.

Używamy również opcji -v (verbose) z cp, aby raportowała, co się dzieje.

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

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

Pliki są kopiowane do dwóch katalogów, po jednym katalogu na raz. cp zgłasza każdą akcję kopiowania pliku, abyśmy mogli zobaczyć, jak mają miejsce.

wyjście xargs i cp w oknie terminala

Usuwanie plików w zagnieżdżonych katalogach

Jeśli nazwy plików zawierają spacje i dziwne znaki – takie jak znaki nowego wiersza – xargs nie będzie w stanie ich poprawnie zinterpretować. Możemy rozwiązać ten problem, używając opcji -0 (terminator zerowy). To mówi xargs, aby używał znaku null jako końcowego separatora dla nazw plików.

W tym przykładzie użyjemy find. find ma własną opcję dla radzenie sobie z białymi znakami i dziwne znaki w nazwach plików. Jest to opcja -print0 (pełna nazwa, znak pusty).

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

To rozpada się w ten sposób:

odnaleźć . -name „* .png”: find będzie szukać w bieżącym katalogu „.” dla obiektów o nazwach pasujących do „* .png”, które są plikami (typ -f).
-print0: nazwy zostaną zakończone znakiem null, a spacje i dziwne znaki zostaną obsłużone.
xargs -0: xargs rozważy również, że nazwy plików są zakończone znakiem null, a spacje i dziwne znaki nie będą powodować problemów.
rm -v -rf „{}”: rm będzie gadać i informować o tym, co się dzieje (-v). Będzie rekurencyjny (-r) i przeglądał zagnieżdżone podkatalogi oraz usuwał pliki bez pytania (-f). Znak „{}” jest zastępowany przez każdą nazwę pliku.

odnaleźć .  -Nazwa

Przeszukiwane są wszystkie podkatalogi, a pliki pasujące do wzorca wyszukiwania są usuwane.

Wyjście rm w oknie terminala

Usuwanie zagnieżdżonych katalogów

Powiedzmy, że chcemy usunąć zestaw zagnieżdżonych podkatalogów. drzewo pozwoli nam je zobaczyć.

tree -d

drzewo -d w oknie terminala

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"

To polecenie użyje find do przeszukiwania rekurencyjnego w bieżącym katalogu. Celem wyszukiwania jest katalog o nazwie „level_one”. Nazwy katalogów są przekazywane przez xargs do rm.

odnaleźć .  -Nazwa

Jedynymi znaczącymi zmianami między tym poleceniem a poprzednim poleceniem jest to, że wyszukiwany termin to nazwa najwyższego katalogu, a -type d mówi findowi, aby szukał katalogów, a nie plików.

wyjście z find, xargs i rm w oknie terminala

Nazwa każdego katalogu jest drukowana, gdy jest usuwana. Możemy sprawdzić w drzewie:

tree -d

drzewo -d w oknie terminala

Wszystkie zagnieżdżone podkatalogi zostaną usunięte.

Usuwanie wszystkich plików z wyjątkiem jednego typu

Możemy użyć find, xargs i rm, aby usunąć wszystkie pliki z wyjątkiem jednego typu, który chcemy zachować. Jest to nieco sprzeczne z intuicją, ale podajemy nazwę typu pliku, który chcemy zachować, a nie nazwę tych, które chcemy usunąć.

Opcja -not mówi find, aby zwracał nazwy plików, które nie pasują do wzorca wyszukiwania. Używamy opcji -I (początkowe argumenty) z xargs jeszcze raz. Tym razem definiowany przez nas token zastępujący ciąg to „{}”. Będzie on zachowywał się dokładnie tak samo, jak wygenerowany wcześniej token zastępujący ciąg, którym był „%”.

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

odnaleźć .  -type f -not - nazwa

Możemy sprawdzić z ls. Jedyne pliki, które pozostały w katalogu, to te, które pasują do wzorca wyszukiwania „* .sh”.

ls -l

wyjście z ls w oknie terminala

Tworzenie pliku archiwum za pomocą Xargs

Możemy użyć find do wyszukania plików i przekazania ich przez xargs do tar, aby utworzyć plik archiwum.

Będziemy szukać w bieżącym katalogu. Wzorzec wyszukiwania to „* .page”, więc będziemy szukać plików „.page”.

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

find ./ - nazwa

Pliki są wyświetlane zgodnie z oczekiwaniami, ponieważ plik archiwum jest tworzony.

wyjście tar w oknie terminala

Mediator danych

Czasami potrzebujesz małego rusztowania, gdy układasz rzeczy razem. xargs wypełnia lukę między poleceniami, które mogą wypompowywać informacje, a poleceniami, które nie są zbudowane do ich pobierania.

Zarówno xargs, jak i find mają ogromną liczbę opcji. Zachęcamy do przejrzenia ich stron podręcznika, aby dowiedzieć się więcej.