xargs

Buduje i uruchamia polecenia z argumentów odczytanych ze standardowego wejścia.

xargs to narzędzie, które czyta dane ze standardowego wejścia i skleja z nich argumenty dla innego polecenia. Brzmi nudno, ale to właśnie ono ratuje Ci życie, gdy chcesz połączyć wynik jednego programu z wejściem drugiego, a ten drugi uparcie nie czyta ze stdin — tylko chce argumenty. Klasyczny duet to find ... | xargs polecenie: find generuje listę plików, a xargs podaje je jako argumenty do rm, grep czy cp. Bonus: xargs sam pilnuje limitu długości linii poleceń, więc nie zobaczysz błędu Argument list too long nawet przy tysiącach plików.

Składnia i najważniejsze opcje

Podstawowa forma to polecenie | xargs [opcje] polecenie_docelowe [argumenty_początkowe]. Jeśli nie podasz polecenia docelowego, xargs domyślnie użyje echo.

  • -0 (--null) — argumenty są rozdzielane bajtem null zamiast białymi znakami. Obowiązkowe, gdy nazwy plików mogą zawierać spacje lub nowe linie (paruj z find ... -print0).
  • -I {} (--replace) — wstawia każdy argument w miejsce {}, uruchamiając polecenie osobno dla każdego elementu. Włącza podział wejścia tylko po nowych liniach.
  • -n N (--max-args) — użyj maksymalnie N argumentów na jedno wywołanie polecenia.
  • -P N (--max-procs) — uruchamiaj do N procesów równolegle. -P 0 odpala tyle, ile się da.
  • -d C (--delimiter) — ustaw własny separator, np. -d '\n', żeby dzielić tylko po liniach.
  • -a plik (--arg-file) — czytaj argumenty z pliku zamiast ze stdin.
  • -p (--interactive) — pytaj o potwierdzenie przed każdym wywołaniem. Przydatne przed usuwaniem.
  • -t (--verbose) — wypisuj budowane polecenie na stderr przed wykonaniem.

Przykłady użycia

  • find . -name "*.log" -print0 | xargs -0 rm — usuwa wszystkie pliki .log, bezpiecznie radząc sobie ze spacjami w nazwach.
  • grep -rl "TODO" . | xargs sed -i 's/TODO/DONE/g' — znajduje pliki z frazą i podmienia ją w każdym z nich.
  • cat lista.txt | xargs -I {} cp {} /backup/ — kopiuje po jednym pliku z listy, wstawiając nazwę w miejsce {}.
  • ls *.jpg | xargs -P 4 -I {} convert {} {}.webp — konwertuje obrazy, uruchamiając 4 procesy równolegle.
  • xargs -a hosty.txt -I {} ping -c1 {} — pinguje po kolei każdy host wczytany z pliku.

Częste błędy i pułapki

Największa mina to spacje i nowe linie w nazwach plików. Domyślnie xargs traktuje białe znaki jako separatory, więc plik moje zdjecie.jpg rozpadnie Ci się na dwa argumenty. Rozwiązanie: zawsze paruj find -print0 z xargs -0. Druga pułapka: gdy wejście jest puste, xargs mimo to raz uruchomi polecenie (z pustą listą) — chyba że dodasz -r (--no-run-if-empty), co jest rozszerzeniem GNU i na macOS/BSD może nie działać. Pamiętaj też, że bez -I lub -n xargs upcha wszystkie argumenty w jedno wywołanie, co bywa niepożądane. I ostrożnie z -P — równoległość jest szybka, ale przy zapisie do jednego pliku łatwo o wyścig.

Powiązane komendy: find, grep, sed, parallel, tr, echo.