Выполнение сложных задач на серверах с Linux часто требует передачи результатов выполнения одного приложения в последующие, иногда сразу в несколько разных. С этой целью и используют утилиту xargs, способную считывать данные со стандартного ввода или ранее сохраненного файла и разбивать на группы согласно заданным параметрам. Способов применения этого продукта масса, и мы в этой статье рассмотрим наиболее популярные.
Полученные в результате сбора данные передаются по цепочке как аргумент. В общем случае синтаксис утилиты xargs для Linux выглядит так:
xargs [-l число] [-I зам_цеп] [-n число] [-t] [-p] [-x] [-s размер] [-e [лконф_цеп]] [команда [начальный_аргумент…]]
Один из самых простых и понятных примеров — удаление файлов по списку, собранному командой find
. Такая процедура необходима, например, для удаления файлов конкретного типа (временных, дублей и т.д.). Чтобы сделать это автоматически по результату поиска, следует передать утилите xargs список удаляемого содержимого, сгенерированного find. Приведем команду для расширения *.sh:
$ ls
one.sh one.py two.sh two.py
$ find . -name "*.sh"| xargs rm -rf
$ ls
one.py two.py
При желании провести такую процедуру можно и без xargs:
$ find . -name "*.sh" -exec rm -rf '{}' \
Правда, приведенная команда может не сработать для файлов, имя которых содержит хотя бы один пробел. Решение проблемы есть: для команды find — это опция print0
, для утилиты xargs — -0
. Их применение позволяет заменить разделитель по умолчанию (перенос строки на нуль-символ). Пример:
$ find . -name "*.sh" -print0 | xargs -0 rm –rf
или
$ find /tmp -name "*.tmp"| xargs rm
Последняя команда нацелена на удаление всех временных файлов.
Еще одна популярная операция — архивация данных, всех находящихся в каталоге или отдельно взятых (например, по расширению). Первое будет выполнено по команде:
$ find . | xargs -p -l gzip
Второй пример показывает, как сжать все файлы с расширением .sh:
$ find . -name "*.sh" | xargs tar -zcf pl.tar.gz
vds
Востребована и процедура пакетного переименования файлов. Многие форматы позволяют делать это, например, чтобы открыть проект в другом приложении без конвертирования структуры. Так, текстовые файлы .TXT в .DOC можно преобразовать при помощи редактора sed:
$ find . | sed -e "p;s/.txt$/.doc/" | xargs -n2 fmv
Результат переименования пользователь увидит на экране, в консоли будет отображен список всех обработанных файлов. В возможности утилиты xargs входит добавление дополнительных символов к имени, например, текущей даты:
$ find . | xargs -I FILE mv {} <...>-{}
Здесь вместо <…> можно подставить любую комбинацию символов. Весьма удобная функция для ручного создания нескольких резервных копий одних и тех же файлов, если проводится их пакетная обработка.
При администрировании серверов пользователи неизбежно сталкиваются с необходимостью менять права на каталоги или отдельные файлы (их группы). Например, чтобы сменить владельца, когда организация обновила штат исполнителей, и новый сотрудник перестраивает систему «под себя». Пример изменения в xargs user1 на user2:
$ find . -group user1 -print | xargs chown user2
Чтобы найти все каталоги с правами user1 и автоматически заменить их на группу user2, пригодится команда:
$ find . -group user1 -print | xargs chgrp user2
Пара утилит find и xgars предоставляет настоящее «поле для экспериментов» благодаря поддержке достаточно сложных по структуре команд с комбинированием различных опций. Пример удаления временных файлов старше 7 календарных дней:
$ find /tmp -type f -name '*' -mtime +7 -print0 | xargs -0 rm -f
Или принудительная остановка процессов, запущенных более 5 дней назад:
$ find /proc -user myuser -maxdepth 1 -type d -mtime +5 -exec basename {} \; | xargs kill -9
При пакетной обработке текстовых файлов может понадобиться функция вырезания отдельных строк (командой cut). Например, нижеследующая команда отобразит на экране полный перечень пользователей:
$ cut -d: -f1 < /etc/passwd | sort | xargs echo
Следующая команда последовательно откроет файлы на редактирование утилитой vim. Сохранение изменений понадобится подтвердить по каждому из них нажатием Y/N.
file * | grep ASCII | cut -d":" -f1 | xargs -p vim
Еще один актуальный пример – поиск самого большого файла в каталоге:
$ find . -type f -printf '%20s %p\n' | sort -n | cut -b22- | tr '\n' '\000' | xargs -0 ls -laSr
Часто используют возможность параллельного запуска однотипных процессов. Например, чтобы заархивировать несколько каталогов в tar.gz:
$ echo dir1 dir2 dir3 | xargs -P 3 -I NAME tar czf NAME.tar.gz NAME
Здесь опция –P
задает максимальное количество одновременно выполняемых процессов. Подобным образом легко поставить на скачивание любое множество файлов:
$ wget -nv <ссылка> | egrep -o "http://[^[:space:]]*.jpg" | xargs -P 10 -n 1 wget –nv
Приведенная команда скачает все изображения с расширением .jpg с указанного сайта, при этом одновременно будет запрашиваться по 10 файлов.
Важно учитывать, что утилита xargs по умолчанию не умеет работать с именами, содержащими пробел. Обойти такое ограничение можно либо применением опции -0
, либо следующим вариантом команды:
$ xargs -I FILE my_command “FILE”
Данные, принятые со стандартного ввода, должны разделятся пробелом или переносом строки. Группировку выполняют при помощи одинарных или двойных кавычек. Иной разделитель можно указать опцией -d
. При отсутствии каких-либо опций выполняется команда /bin/echo.
В ряде случаев xarg можно заменить циклом for
:
$ find . -type f -and -iname "*.deb" | xargs -n 1 dpkg –I
или
$ for file in `find . -type f -and -iname "*.deb"`; do dpkg -I "$file
Выше мы рассмотрели стандартные операции. На практике же встречается масса весьма интересных ситуаций, когда утилита xargs позволяет оперативно решить задачи вроде блокировки конкретных хостов или генерирования уникальных паролей.
Непосредственно бан осуществляется сетевым экраном IPTables. Но внести в него список адресов для блокировки можно при помощи xargs (правило DROP обязательно):
$ cat bad_ip_list | xargs -I IP iptables -A INPUT -s IP -j DROP
Преобразование вида ссылки может понадобиться при работе с поддоменами. Попробуем сделать это, изменив http://www.new.domen.com в http://www.domen.com.
echo "http://www.new.domen.com" | sed -e's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g' | xargs echo -e
Команда для создания уникального пароля из случайного набора 8 символов:
$ tr -dc A-Za-z0-9_ < /dev/urandom | head -c 8 | xargs
Конечно, для этой цели существует отдельное решение, утилита pwgen, но знать и о таком способе полезно.
Процедура востребована при ручном удалении вирусной активности, когда на удаленный хост была совершена атака с инъекцией вредоносного кода. Обычно такие бинарники устанавливаются «мимо» менеджера пакетов dpkg и легко обнаруживаются по данному признаку:
$ сat /var/lib/dpkg/info/*.list > /tmp/listin ; ls /proc/*/exe |xargs -l readlink | grep -xvFf /tmp/listin; rm /tmp/listin
Остается также пакетно удалить их при помощи той же утилиты.
Полезно знать, как быстро освободить место на диске от неактуальных обновлений:
$ dpkg -l linux-* | awk '/^ii/{ print $2}' | grep -v -e `uname -r | cut -f1,2 -d"-"` | grep -e [0-9] | xargs sudo apt-get -y purge
Разверните свой Linux VDS в Timeweb Cloud
Приведенные примеры использования утилиты xargs показывают, почему она столь популярна в среде системных администраторов. Типовые функции — это лишь вершина айсберга, и при должной фантазии этот продукт легко превратить в повседневный инструмент с разнообразными задачами, большинство которых реально автоматизировать и тем самым снизить риски ошибок из-за человеческого фактора.