Внутри находится еще один цикл for
, который следит за количеством процессов, запущенных к данному моменту. Этот внутренний цикл также использует команду seq для организации итераций от 0 до максимального числа процессов с шагом, по умолчанию равным 1. В каждой итерации внутренний цикл for извлекает новый файл из списка
, вызывая sed, чтобы вывести только требуемое имя файла из списка, сохраненного в начале сценария, и запускает указанную команду с этим файлом в фоновом режиме с применением знака &.
После запуска максимального количества процессов сценарий вызывает команду wait
, которая приостанавливает его выполнение до момента, когда завершатся все команды, запущенные в фоновом режиме. После того как wait завершится, вновь начинается процедура запуска процессов для обработки остальных файлов. Она похожа на процедуру выбора лучшей программы сжатия в сценарии bestcompress (сценарий № 34 в главе 4).
Пользоваться сценарием bulkrun очень просто. Ему нужно передать три аргумента: максимальное количество одновременно действующих процессов, каталог с файлами для обработки и запускаемую команду. Например, в листинге Б.4 показано, как изменить размеры изображений в каталоге, запустив одновременно несколько экземпляров утилиты mogrify из пакета ImageMagick.
Листинг Б.4.Запуск команды bulkrun для параллельной обработки файлов изображений утилитой mogrify из пакета ImageMagick
$ bulkrun −p 3 −i tmp/ −x "mogrify −resize 50 %"
Running mogrify −resize 50 % tmp//1024-2006_1011_093752.jpg
Running mogrify −resize 50 % tmp//069750a6-660e-11e6-80d1-001c42daa3a7.jpg
Running mogrify −resize 50 % tmp//06970ce0-660e-11e6-8a4a-001c42daa3a7.jpg
Running mogrify −resize 50 % tmp//0696cf00-660e-11e6-8d38-001c42daa3a7.jpg
Running mogrify −resize 50 % tmp//0696cf00-660e-11e6-8d38-001c42daa3a7.jpg
-опущено-
Усовершенствование сценария
Часто бывает полезно иметь возможность указать имя файла внутри команды или использовать лексемы, подобные тем, что упоминались в описании сценария bulkrename (сценарий № 102 выше): специальные строки, динамически заменяемые во время выполнения фактическими значениями (например, %d можно было бы заменять текущей датой, или %t отметкой текущего времени). Реализация поддержки подобных специальных лексем в команде или в именах файлов стала бы ценным усовершенствованием сценария.
Другим полезным усовершенствованием было бы использование утилиты time для определения продолжительности обработки всех файлов. Вывод статистической информации о количестве обработанных файлов или файлов, ожидающих обработки, тоже мог бы пригодиться в случае выполнения массивных заданий.
№ 104. Определение фазы Луны
Если вы оборотень, ведьма или просто интересуетесь лунным календарем, вам наверняка пригодится полезная и познавательная возможность определять фазы Луны.
Вся сложность в том, что Луна совершает полный оборот вокруг Земли за 27,32 дня. И ее фаза фактически зависит от вашего местоположения на Земле. Однако эта зависимость невелика, так что фазы Луны можно определять только по заданной дате.
Но зачем разбираться со всеми этими сложностями, если в Интернете полно сайтов, которые вычисляют фазу Луны для любой даты в прошлом, в настоящем или в будущем? Для сценария в листинге Б.5 мы используем для этого тот же сайт, что использует Google: http://www.moongiant.com/.
Листинг Б.5.Сценарий moonphase
··#!/bin/bash
··# moonphase — сообщает фазу Луны (в действительности процент
··#·· освещенности) на текущую или указанную дату.
··# Формат запроса к Moongiant.com:
··#·· http://www.moongiant.com/phase/MM/DD/YYYY
··# Если дата не указана, использовать текущую дату.
··if [$# −eq 0]; then
····thedate="today"
··else
····# Дата указана. Проверить правильность ее формата.
····mon="$(echo $1 | cut −d/ −f1)"
····day="$(echo $1 | cut −d/ −f2)"
····year="$(echo $1 | cut −d/ −f3)"
····if [-z "$year" −o — z "$day"]; then # Нулевая длина?
······echo "Error: valid date format is MM/DD/YYYY"
······exit 1
····fi
····thedate="$1" # Отсутствие проверки ошибок = опасность.
··fi
··url="http://www.moongiant.com/phase/$thedate"
··pattern="Illumination: "
··phase="$(curl −s "$url" | grep "$pattern" | tr ',' '\
Читать дальше