У меня есть скрипт bash, который выглядит так:
#!/bin/bash
wget LINK1 >/dev/null 2>&1
wget LINK2 >/dev/null 2>&1
wget LINK3 >/dev/null 2>&1
wget LINK4 >/dev/null 2>&1
# ..
# ..
wget LINK4000 >/dev/null 2>&1
Но обработка каждой строки до тех пор, пока команда не завершится, а переход к следующей занимает очень много времени, я хочу обработать, например, 20 строк одновременно, а затем, когда они завершатся, будут обработаны еще 20 строк.
Я думал о том, wget LINK1 >/dev/null 2>&1 &
чтобы отправить команду в фоновый режим и продолжить, но здесь 4000 строк, это означает, что у меня будут проблемы с производительностью, не говоря уже об ограничении количества процессов, которые я должен запускать одновременно, так что это не очень хорошо идея.
Одним из решений, о котором я сейчас думаю, является проверка, выполняется ли еще одна из команд или нет, например, после 20 строк я могу добавить этот цикл:
while [ $(ps -ef | grep KEYWORD | grep -v grep | wc -l) -gt 0 ]; do
sleep 1
done
Конечно, в этом случае мне нужно будет добавить & в конец строки! Но я чувствую, что это не правильный способ сделать это.
Итак, как мне на самом деле сгруппировать каждые 20 строк и ждать, пока они закончат, прежде чем перейти к следующим 20 строкам, этот сценарий генерируется динамически, поэтому я могу делать с ним все, что захочу, пока он генерируется, но он НЕ ДОЛЖЕН используйте wget, это был просто пример, так что любое решение, специфичное для wget, не принесет мне пользы.
wait
здесь правильный ответ, но вашwhile [ $(ps …
будет гораздо лучше написанwhile pkill -0 $KEYWORD…
- используя proctools … то есть, по уважительным причинам, чтобы проверить, все еще ли запущен процесс с определенным именем.Ответы:
Используйте
wait
встроенные:В приведенном выше примере 4 процесса
process1
...process4
будут запущены в фоновом режиме, и оболочка будет ожидать завершения этих процессов перед запуском следующего набора.Из руководства GNU :
источник
i=0; waitevery=4; for link in "${links[@]}"; do wget "$link" & (( i++%waitevery==0 )) && wait; done >/dev/null 2>&1
Смотрите параллельно . Его синтаксис похож на
xargs
, но он выполняет команды параллельно.источник
wait
, так как он заботится о запуске новых заданий как завершенных старых, а не о ожидании завершения всего пакета перед началом следующего.cat list_of_links.txt | parallel -j 4 wget {}
, чтобы одновременноwget
работали четыре файла .parallel
.parallel --jobs 4 < list_of_commands.sh
где list_of_commands.sh - файл с одной командой (напримерwget LINK1
, примечание без&
) в каждой строке. Возможно, потребуется сделатьCTRL+Z
иbg
после этого оставить его работающим в фоновом режиме.На самом деле,
xargs
может запускать команды параллельно для вас. Для этого есть специальный параметр-P max_procs
командной строки. Смman xargs
.источник
Вы можете запустить 20 процессов и использовать команду:
Ваш сценарий будет ждать и продолжать, когда все ваши фоновые задания будут завершены.
источник