Привет коллега! Надеюсь ты выжил после выходных и не сорвал спину на мероприятии по копке картофеля. Сегодня у нас с тобой bash.
Мы прекрасно знаем, что bash скрипты выполняются последовательно. Но есть ли способы запускать команды параллельно?
Конечно есть, сейчас про это и поговорим. Покажу два способа как это можно легко осуществить. Первый способ основан на символе &.
Пишем подопытный скрипт:
Wait – команда, которая ожидает завершения определенного процесса, а затем возвращает его состояние завершения.
Оболочка ждет (wait) пока завершатся два предыдущих процесса, прежде чем запустить следующую команду. Получается, все то, что в скрипте идет после wait, будет в режиме ожидания, пока не завершится первый sleep и второй.
Прикольно да? Открываются новые возможности для совершенствования своих костылей. Прям терпко попахивает асинхронностью, в хорошем смысле. Про wait поговорим в отдельном посте, есть там свои клевые фичи.
Теперь давай запустим в терминале последовательно такие команды:
Команда jobs в Linux позволяет пользователю напрямую взаимодействовать с процессами в текущей оболочке. Команда отображает состояние заданий в текущем сеансе.
Запускаем jobs и смотрим:
Давай теперь напишем более наглядный пример, где всё это можно применить.
2. Передает каждую строчку в функцию downloader
3. Функция downloader каждый раз запускается в фоне
4. Происходит скачивание файла по ссылке
5. По завершению (wait) получаемкомпливит complete
Файл url.txt представляет собой список прямых урлов на файлы, которые нужно скачать.
Получается мы не дожидаемся пока скачается первый файл, а сразу скачиваем все пачкой. Мультизагрузка.
Если совсем уж по-простому, то символ & говорит — запусти всё одновременно и параллельно. Типа такого, с таким ты уже всяко встречался:
Это основной вариант, советую его и использовать, теперь давай рассмотрим альтернативные.
Есть еще такая утилита parallel, устанавливается как и все остальное
Углубляться сейчас в parallel особого смысла не вижу, но для общего кругозора ты про нее должен знать. Иногда бывает что для решения задачи подойдет именно parallel, а не нативка с &.
Ну и на закуску, есть такая штука «$!», она позволяет узнать PID последнего запущенного процесса. Давай на примере, запускай:
Вот так это и работает. Ничего сложного. Надеюсь было интересно. Хорошего тебе понедельника, увидимся!
tags: #bash #linux #utils
—
💩 @bashdays
Мы прекрасно знаем, что bash скрипты выполняются последовательно. Но есть ли способы запускать команды параллельно?
Конечно есть, сейчас про это и поговорим. Покажу два способа как это можно легко осуществить. Первый способ основан на символе &.
Пишем подопытный скрипт:
#!/bin/bashЗдесь первая и вторая команда запустятся параллельно. Через 5 секунд на экран выведутся 3 строчки sleep 5_1, sleep 5_2 и sleep 0.
sleep 5 && echo "sleep 5_1" &
sleep 5 && echo "sleep 5_2" &
wait
echo "sleep 0"
Wait – команда, которая ожидает завершения определенного процесса, а затем возвращает его состояние завершения.
Оболочка ждет (wait) пока завершатся два предыдущих процесса, прежде чем запустить следующую команду. Получается, все то, что в скрипте идет после wait, будет в режиме ожидания, пока не завершится первый sleep и второй.
Прикольно да? Открываются новые возможности для совершенствования своих костылей. Прям терпко попахивает асинхронностью, в хорошем смысле. Про wait поговорим в отдельном посте, есть там свои клевые фичи.
Теперь давай запустим в терминале последовательно такие команды:
sleep 60 &На экран выведутся записи вроде таких:
sleep 90 &
sleep 120 &
[1] 38161Это PID процессов которые ты запустил в фоновом режиме. Но интересует нас тут другое. А именно команда jobs.
[2] 38166
[3] 38167
Команда jobs в Linux позволяет пользователю напрямую взаимодействовать с процессами в текущей оболочке. Команда отображает состояние заданий в текущем сеансе.
Запускаем jobs и смотрим:
[1] Done sleep 60Опа! А это список команд, которые мы запустили в фоне. Первое задание завершилось, остальное еще шуршит. Некий мониторинг из коробки.
[2]- Running sleep 90 &
[3]+ Running sleep 120 &
Давай теперь напишем более наглядный пример, где всё это можно применить.
downloader(){1. Скрипт читает построчно файл url.txt
wget -q "$1"
}
while IFS= read -r url
do
downloader "$url" &
done < urls.txt
wait
echo "Downloaded complete"
2. Передает каждую строчку в функцию downloader
3. Функция downloader каждый раз запускается в фоне
4. Происходит скачивание файла по ссылке
5. По завершению (wait) получаем
Файл url.txt представляет собой список прямых урлов на файлы, которые нужно скачать.
Получается мы не дожидаемся пока скачается первый файл, а сразу скачиваем все пачкой. Мультизагрузка.
Если совсем уж по-простому, то символ & говорит — запусти всё одновременно и параллельно. Типа такого, с таким ты уже всяко встречался:
hostname & date & uname &Тут все запустится одновременно и порядок вывода на экран будет каждый раз в своем порядке. Все зависит с какой скоростью отработает команда.
Это основной вариант, советую его и использовать, теперь давай рассмотрим альтернативные.
Есть еще такая утилита parallel, устанавливается как и все остальное
apt/yum/brew install parallel
Делает она то же самое, но имеет более гибкие настройки через параметры. Например, предыдущий пример со скачиванием файлов мог бы выглядеть таким образом:parallel -j 4 wget -q {} < urls.txtКлюч -j означает сколько джобов будет запараллелено, что-то типа потоков/threads.
Углубляться сейчас в parallel особого смысла не вижу, но для общего кругозора ты про нее должен знать. Иногда бывает что для решения задачи подойдет именно parallel, а не нативка с &.
Ну и на закуску, есть такая штука «$!», она позволяет узнать PID последнего запущенного процесса. Давай на примере, запускай:
sleep 60 &В первой команде запустили фоном ожидание 60 секунд, вывелся порядковый номер джобы и PID. Ну а чтобы получить последний PID, выполняем третью команду с «$!». На экран вывелся PID в чистом виде, а дальше можешь его сохранить в переменную и уже проверять в скрипте, завершился он или нет.
[1] 39032
echo $!
39032
Вот так это и работает. Ничего сложного. Надеюсь было интересно. Хорошего тебе понедельника, увидимся!
tags: #bash #linux #utils
—