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: standardowy strumień wejściowy (stdin), standardowy strumień wyjściowy (stdout) oraz 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

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

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

ls -1 ./*.sh | xargs

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

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

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ń.

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 touch, przez xargs, touch utworzy pliki dla nas.

echo 'one two three' | xargs -p touch

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”.

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

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 tree ignoruje pliki i raportuje tylko o katalogach.

tree -d

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

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 directories.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.

Katalogi są wymienione jeden po drugim.

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

tree -d

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

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.

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 radzenia 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:

  • find . -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.

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

Usuwanie zagnieżdżonych katalogów

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

tree -d

find . -name "level_one" -type d -print0 | xargs -0 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.

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

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

tree -d

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 {}

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

ls -l

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

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

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.


newsblog.pl