GNU parallel: Ускорьте выполнение команд Bash в разы
Вы когда-нибудь сталкивались с ситуацией, когда стандартный цикл for в Bash слишком медленно обрабатывает сотни или тысячи файлов, выполняя каждую операцию последовательно? Будь то сжатие изображений, конвертация видеофайлов или массовая загрузка данных, for задействует только одно ядро процессора, оставляя остальные в простое. В результате вы тратите драгоценное время на ожидание.
Утилита parallel кардинально меняет подход, запуская задачи параллельно и эффективно используя все доступные ядра процессора. Это позволяет сократить время выполнения операций с часов до минут. Помимо существенного прироста производительности, parallel предлагает удобные функции отображения прогресса и ведения логов.
🟢 Как установить GNU parallel:
Установка parallel проста и доступна в большинстве популярных дистрибутивов Linux, а также на macOS.
Ubuntu/Debian
sudo apt install parallel
CentOS/RHEL/Fedora
sudo dnf install parallel
Arch Linux
sudo pacman -S parallel
macOS
brew install parallel
🟢 Базовое использование (проще, чем кажется):
Освоение parallel не требует глубоких знаний. Вот несколько наглядных примеров:
1. Сжать все JPEG-файлы одним залпом:
find . -name "*.jpg" | parallel -j+0 jpegoptim --strip-all {}
Здесь -j+0 указывает parallel использовать все доступные ядра процессора, а {} выступает в качестве заполнителя для каждого имени файла, передаваемого из find.
2. Конвертировать все JPG в PNG:
parallel convert {} {.}.png ::: *.jpg
Опция {.} позволяет получить имя файла без расширения. Символ ::: используется для передачи списка файлов напрямую из командной строки.
3. Скачать 10 файлов одновременно из списка:
cat urls.txt | parallel -j 10 curl -O {}
Эта команда загрузит 10 файлов параллельно, что особенно полезно при работе с большим количеством URL и позволяет избежать перегрузки сервера.
4. Создать 100 папок мгновенно:
seq 100 | parallel mkdir "dir_{}"
Вместо последовательного создания директорий, которое может занять минуту, parallel выполнит эту задачу за считанные секунды.
➕ Преимущества:
- Скорость: Максимальное использование вычислительных ресурсов за счёт задействования всех ядер.
- Гибкость: Совместимость с такими утилитами, как find, xargs, grep, и поддержка любых команд Bash.
- Интеллектуальное логирование: Возможность отслеживать прогресс выполнения задач и сохранять подробные отчёты.
- Портативность: Доступность в стандартных репозиториях большинства операционных систем.
➖ Недостатки:
- Отсутствие предустановки: На минимальных установках системы
parallelможет отсутствовать. - Риск перегрузки: Неконтролируемое число потоков может привести к избыточной нагрузке на аппаратное обеспечение.
- Сложное экранирование: Для некоторых сложных команд может потребоваться тщательное экранирование символов.
🔴 Ключевые функции:
1. Отображение прогресса и создание отчётов:
parallel --progress --joblog log.txt convert {} {.}.png ::: *.jpg
Эта команда отображает текущий прогресс выполнения задач и сохраняет детальный отчёт в файл log.txt.
2. Ограничение числа одновременных задач:
parallel -j 4 gzip ::: *.log
Использование опции -j 4 ограничивает количество одновременно выполняемых процессов до четырех, предотвращая чрезмерную нагрузку на сервер. Здесь также демонстрируется сжатие файлов с помощью gzip.
3. Работа с удалёнными серверами:
parallel -S server1,server2 uptime
parallel позволяет выполнять команды на нескольких удалённых серверах одновременно, что удобно для мониторинга и управления инфраструктурой.
4. Комбинация с find и сложными командами:
find . -name "*.avi" | parallel 'ffmpeg -i {} {.}.mp4 && rm {}'
Этот пример демонстрирует мощь parallel, которая позволяет параллельно конвертировать видеофайлы и затем удалять исходники, используя команду rm.
Когда что использовать?
-
parallel— идеален для массовой обработки файлов, когда каждая операция независима от других. -
for— подходит для простых последовательных операций или когда критичен порядок выполнения. -
xargs -P— является альтернативойparallel, если последний не установлен, но обладает менее удобным синтаксисом.
Лайфхак:
Добавьте в свой файл .bashrc удобный алиас для параллельной загрузки:
alias parcurl='parallel -j 10 curl -O'
Теперь, вместо того чтобы ждать, пока 500 файлов обработаются по одному, вы можете запустить все ядра процессора и спокойно выпить кофе. Эта автоматизация особенно полезна на серверах с большим количеством вычислительных ядер.