Команда Linux xargs: Построение команд

LinuxLinuxBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии (лабораторной работе) вы познакомитесь с мощной командой xargs в Linux. Команда xargs - это универсальный инструмент, который позволяет создавать и выполнять команды на основе стандартного ввода. Она особенно полезна для обработки списков аргументов и преобразования их в командные строки.

В рамках этого практического занятия мы будем использовать концепцию "обработки книг" в качестве примера задачи. Важно отметить, что "обработка книг" не является конкретной командой Linux, а скорее представляет собой заполнитель для любой операции, которую вы можете хотеть выполнить над списком элементов. В наших примерах мы часто будем использовать простые команды, такие как echo или touch, чтобы имитировать эту обработку. В реальных сценариях вы замените эти команды более сложными командами или скриптами, соответствующими вашей конкретной задаче.

По завершении этого практического занятия вы сможете эффективно управлять файлами и автоматизировать повторяющиеся задачи с использованием xargs. Это практическое занятие предназначено для начинающих, поэтому не беспокойтесь, если вы новичок в Linux - мы подробно проведем вас через каждый шаг.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/BasicSystemCommandsGroup(["Basic System Commands"]) linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) linux/BasicSystemCommandsGroup -.-> linux/xargs("Command Building") linux/BasicFileOperationsGroup -.-> linux/cat("File Concatenating") subgraph Lab Skills linux/xargs -.-> lab-219201{{"Команда Linux xargs: Построение команд"}} linux/cat -.-> lab-219201{{"Команда Linux xargs: Построение команд"}} end

Понимание команды xargs

Начнем с понимания базового использования команды xargs. Мы используем простой пример, чтобы показать, как xargs работает с вводом из файла.

Сначала посмотрим на содержимое файла, который содержит список фруктов:

cat ~/project/fruits.txt

Вы должны увидеть следующий вывод:

apple
orange
banana

Теперь используем xargs для вывода содержимого этого файла с помощью команды echo:

cat ~/project/fruits.txt | xargs echo

Вы должны увидеть следующий вывод:

apple orange banana

В этом примере xargs берет ввод от команды cat и использует его в качестве аргументов для команды echo. Здесь команда echo имитирует нашу "обработку". По умолчанию xargs рассматривает каждую строку как отдельный аргумент и объединяет их в одну команду.

Разберем, что здесь происходит:

  1. cat ~/project/fruits.txt читает содержимое файла.
  2. Символ | (канал) отправляет этот вывод следующей команде.
  3. xargs echo берет каждую строку из ввода и использует ее в качестве аргумента для команды echo.

Это полезно, так как позволяет обрабатывать несколько элементов одной командой, что может быть гораздо более эффективно, чем обработка каждого элемента по отдельности. В реальных приложениях вы замените echo любой командой или скриптом, который вам нужно запустить для каждого элемента в списке.

Обработка файлов с использованием xargs

Представьте, что вы библиотекарь, которому поручено организовать цифровой архив. У вас есть список названий книг, и вам нужно создать пустые файлы для каждой книги. Давайте используем xargs для автоматизации этого процесса.

Сначала посмотрим на содержимое файла, содержащего названия некоторых книг:

cat ~/project/books.txt

Вы должны увидеть:

The_Great_Gatsby
To_Kill_a_Mockingbird
1984

Теперь используем xargs вместе с командой touch для создания пустых файлов для каждой книги:

cat ~/project/books.txt | xargs -I {} touch ~/project/{}.txt

Разберем эту команду:

  • cat ~/project/books.txt: Эта команда читает содержимое нашего файла со списком книг.
  • |: Этот символ канала (pipe) отправляет вывод команды cat следующей команде.
  • xargs: Это наша команда для создания и выполнения команд на основе стандартного ввода.
  • -I {}: Этот параметр сообщает xargs заменить все вхождения {} в команде каждой строкой ввода.
  • touch ~/project/{}.txt: Это команда, которую xargs выполнит для каждой строки ввода. Символ {} будет заменен на каждое название книги.

Эта команда использует параметр -I {} для указания заполнителя ({}) для каждого входного элемента. Для каждой строки в books.txt xargs заменит {} названием книги и выполнит команду touch.

Проверим, были ли созданы файлы:

ls ~/project/*.txt

Вы должны увидеть следующий вывод:

/home/labex/project/1984.txt
/home/labex/project/The_Great_Gatsby.txt
/home/labex/project/To_Kill_a_Mockingbird.txt
/home/labex/project/books.txt
/home/labex/project/fruits.txt

Как вы можете видеть, xargs создал новый файл с расширением.txt для каждого названия книги, а также сохранил наши исходные файлы books.txt и fruits.txt.

Ограничение аргументов с помощью xargs

По мере роста нашего цифрового библиотеки мы хотим обрабатывать книги небольшими партиями. Опция -n команды xargs позволяет нам ограничить количество аргументов, передаваемых при каждом выполнении команды.

Посмотрим на файл с большим количеством названий книг:

cat ~/project/more_books.txt

Вы должны увидеть:

Pride_and_Prejudice
The_Catcher_in_the_Rye
The_Hobbit
Animal_Farm
Brave_New_World

Теперь используем xargs с опцией -n для обработки по две книги за раз:

cat ~/project/more_books.txt | xargs -n 2 echo "Processing books:"

Вы должны увидеть вывод, похожий на следующий:

Processing books: Pride_and_Prejudice The_Catcher_in_the_Rye
Processing books: The_Hobbit Animal_Farm
Processing books: Brave_New_World

Разберем, что здесь происходит:

  • cat ~/project/more_books.txt: Эта команда читает содержимое нашего файла со списком книг.
  • |: Этот символ канала (pipe) отправляет вывод команды cat следующей команде.
  • xargs -n 2: Это сообщает xargs использовать не более 2 аргументов при каждом выполнении команды.
  • echo "Processing books:": Это команда, которую xargs будет выполнять, с названиями книг в качестве дополнительных аргументов.

Эта команда обрабатывает книги парами, при этом последняя книга обрабатывается отдельно, если количество названий нечетное. Опция -n полезна, когда вы хотите обрабатывать элементы определенными группами, что может быть полезно для управления большими списками или для команд, которые имеют ограничение на количество аргументов, которые они могут обработать.

Параллельная обработка с использованием xargs

По мере дальнейшего расширения нашей библиотеки мы хотим ускорить обработку файлов. Опция -P команды xargs позволяет запускать команды параллельно, что может существенно повысить производительность при выполнении операций, ограниченных вводом-выводом (I/O-bound operations).

Сначала создадим скрипт, который имитирует обработку книги путем добавления временной метки к ее содержимому:

cat ~/project/process_book.sh

Вы должны увидеть:

#!/bin/bash
echo "Processing $1 at $(date)" > ~/project/processed_$1
sleep 2 ## Simulate some processing time

Этот скрипт выполняет следующие действия:

  1. Он принимает название книги в качестве аргумента ($1).
  2. Он создает новый файл с префиксом "processed_" перед названием книги.
  3. Он записывает сообщение в этот файл, включающее текущую дату и время.
  4. Он ждет 2 секунды, чтобы имитировать время обработки.

Теперь используем xargs с опцией -P для параллельной обработки книг:

cat ~/project/more_books.txt | xargs -P 3 -I {} ~/project/process_book.sh {}

Разберем эту команду:

  • cat ~/project/more_books.txt: Эта команда читает наш список книг.
  • |: Этот символ канала (pipe) отправляет вывод в xargs.
  • xargs -P 3: Это сообщает xargs запускать до 3 процессов параллельно.
  • -I {}: Это определяет {} как заполнитель для каждого входного элемента.
  • ~/project/process_book.sh {}: Это команда, которая будет выполнена для каждой книги, при этом {} заменяется на название книги.

Эта команда начнет обрабатывать до 3 книг одновременно. После выполнения команды вы можете проверить содержимое обработанных файлов:

cat ~/project/processed_*

Вы должны увидеть вывод, показывающий, что книги были обработаны в немного разное время, что указывает на параллельное выполнение. Точные времена могут отличаться, но вы, возможно, увидите что-то вроде этого:

Processing Pride_and_Prejudice at Mon Aug 12 10:15:01 UTC 2024
Processing The_Catcher_in_the_Rye at Mon Aug 12 10:15:01 UTC 2024
Processing The_Hobbit at Mon Aug 12 10:15:01 UTC 2024
Processing Animal_Farm at Mon Aug 12 10:15:03 UTC 2024
Processing Brave_New_World at Mon Aug 12 10:15:03 UTC 2024

Обратите внимание, как первые три книги начинают обрабатываться одновременно, а последние две начинают обрабатываться примерно через 2 секунды (из-за команды sleep 2 в нашем скрипте). Это демонстрирует работу параллельной обработки.

Комбинирование опций xargs

Для нашей последней задачи мы рассмотрим, как обрабатывать книги партиями, при этом используя параллельную обработку. Мы применим несколько другой подход, чем изначально предложенный, чтобы избежать взаимоисключаемости опций -n и -I.

Посмотрим на наш список классических книг:

cat ~/project/classic_books.txt

Вы должны увидеть:

Moby_Dick
War_and_Peace
Ulysses
Don_Quixote
The_Odyssey
Madame_Bovary
Lolita
Hamlet
The_Iliad
Crime_and_Punishment

Теперь используем xargs для обработки этих книг партиями по 2, с максимальным количеством параллельных процессов равным 3:

cat ~/project/classic_books.txt | xargs -n 2 -P 3 sh -c 'echo "Processing batch: $0 $1"'

Разберем эту команду:

  • cat ~/project/classic_books.txt: Эта команда читает наш список классических книг.
  • |: Этот символ канала (pipe) отправляет вывод в xargs.
  • xargs: Это наша команда для создания и выполнения команд на основе стандартного ввода.
  • -n 2: Эта опция сообщает xargs использовать 2 аргумента (названия книг) при каждом выполнении команды.
  • -P 3: Эта опция сообщает xargs запускать до 3 процессов параллельно.
  • sh -c 'echo "Processing batch: $0 $1"': Это команда, которую xargs будет выполнять. Она использует оболочку (shell) для вывода названий книг. $0 и $1 представляют два названия книг, переданных xargs.

Вы должны увидеть вывод, похожий на следующий:

Processing batch: Moby_Dick War_and_Peace
Processing batch: Ulysses Don_Quixote
Processing batch: The_Odyssey Madame_Bovary
Processing batch: Lolita Hamlet
Processing batch: The_Iliad Crime_and_Punishment

Эта команда демонстрирует, как можно эффективно обрабатывать большое количество элементов партиями, при этом используя параллельную обработку. В данном случае мы обрабатываем книги парами (из-за -n 2) и запускаем до трех таких команд обработки пар параллельно (из-за -P 3).

Преимущество этого подхода заключается в том, что он позволяет обрабатывать элементы в управляемых частях (в данном случае, парами книг), при этом используя параллельную обработку для ускорения всей операции. Это может быть особенно полезно при работе с большими наборами данных или когда необходимо найти баланс между скоростью обработки и использованием системных ресурсов.

В реальной ситуации вы можете заменить команду echo более сложным скриптом обработки. Например, вы можете модифицировать наш предыдущий скрипт process_book.sh так, чтобы он обрабатывал сразу две книги, а затем использовать его вместо команды echo.

Резюме

В этом практическом занятии вы научились использовать команду xargs для автоматизации задач по управлению файлами. Вы изучили ее базовое использование, научились обрабатывать файлы, ограничивать аргументы, выполнять параллельную обработку и комбинировать опции для эффективной пакетной обработки. Эти навыки будут неоценимы, когда вам нужно будет обрабатывать большие объемы данных или автоматизировать повторяющиеся задачи в среде Linux.

Вот некоторые дополнительные опции xargs, которые не были рассмотрены в практическом занятии:

  • -0: Использовать нулевой символ в качестве разделителя вместо пробелов
  • -L: Использовать не более max-lines непустых строк ввода на каждую строку команды
  • -s: Использовать не более max-chars символов на каждую строку команды
  • -r: Не запускать команду, если стандартный ввод пуст
  • -a: Читать элементы из файла вместо стандартного ввода
  • -E: Установить строку конца файла (EOF)

Помните, что мощь xargs заключается в ее гибкости и способности работать с другими командами Linux. По мере дальнейшей работы с Linux вы обнаружите еще много ситуаций, когда xargs поможет вам автоматизировать задачи и повысить продуктивность.