В Fedora 25, settings/universal access/typing/repeat keys, установите значение off, чтобы полностью отключить залипание клавиш или настроить задержку и скорость по своему вкусу
Ответ Confiq хорош для небольших i
и j
. Однако, учитывая размер i
и j
в вашем вопросе, вы, вероятно, захотите ограничить общее количество порожденных процессов. Вы можете сделать это с помощью команды parallel
или некоторых версий xargs
. Например, используя xargs, который поддерживает флаг -P
, вы можете распараллелить свой внутренний цикл следующим образом:
for i in {0800..9999}; do
echo {001..032} | xargs -n 1 -P 8 -I{} wget http://example.com/"$i-{}".jpg
done
GNU parallel имеет большое количество функций, когда вам нужно более сложное поведение, и упрощает распараллеливание по обоим параметрам:
parallel -a <(seq 0800 9999) -a <(seq 001 032) -P 8 wget http://example.com/{1}-{2}.jpg
for i in {1..3}; do
for j in {10..20}; do
(wget http://example.com/"$i-$j".jpg &)
done
done
Я даже проверял...
Вот очень упрощенный подход. Ограничивает потоки до 10 в этом примере.
for i in {0800..9999}; do
for j in {001..032}; do
wget http://example.com/"$i-$j".jpg &
while test $(jobs -p|wc -w) -ge 10; do sleep 0.1 ; done
done
done
Примерно так я решил ту же проблему в среде, где parallel
не было доступно. Это зависит от функций bash, поэтому вам нужно #!/bin/bash
или явно выполнить скрипт через bash.
MAX_CONCURRENT=50
n=0
some_command_that_outputs_urls \
| while read url
do
{
do_something_with $url
} &
PIDS="$PIDS $!"
((++n))
if test "$n" -ge "$MAX_CONCURRENT"
then
n=0
wait $PIDS
PIDS=""
fi
done
test -n "$PIDS" && wait $PIDS
Можно настроить $MAX_CONCURRENT
, чтобы указать желаемое (приблизительное )максимальное количество потоков. И, конечно же, вы замените some_command_that_outputs_urls
и do_something_with $url
тем, что подходит для вашего сценария. Например, вы можете заменить строку some_command_that_outputs_urls \
на
for i in {0800..9999}; do
for j in {001..032}; do
printf 'http://example.com/%s-%s.jpg\n' $i $j
done
done \
#...| while read url...
и do_something_with $url
просто с
wget $url
окончательный результат
MAX_CONCURRENT=50
n=0
for i in {0800..9999}; do
for j in {001..032}; do
printf 'http://example.com/%s-%s.jpg\n' $i $j
done
done \
| while read url
do
{
wget $url
} &
PIDS="$PIDS $!"
((++n))
if test "$n" -ge "$MAX_CONCURRENT"
then
n=0
wait $PIDS
PIDS=""
fi
done
test -n "$PIDS" && wait $PIDS
Это работает следующим образом: команда генерирует список (в данном случае )URL-адресов на своем стандартном выходе и считывает эту строку за раз в цикл while
(watch для новых строк! ). Он будет порождать до $MAX_CONCURRENT
одновременных процессов, используя $n
для отслеживания количества порожденных процессов и $PIDS
для записи их идентификаторов процессов. После того, как $MAX_CONCURRENT
процессы были порождены (, обратите внимание, что то, что действительно порождается, является составным оператором, поэтому вы можете иметь несколько команд и даже блоков внутри него ), это будет wait
на порожденных PID (это немедленно возвращается, если ни один из указанных PID все еще не выполняется )и сбрасывает свое внутреннее состояние, затем переходит к другому запуску.
Есть несколько способов улучшить этот сценарий, включая улучшенную обработку повторно используемых PID, но он выполняет работу, которую я хотел, в среде, в которой он должен работать, поэтому он достаточно хорош для меня. В моей текущей версии также есть тайм-аут, и он регулярно -выполняется через cron, поэтому риск неконтролируемого времени выполнения намного меньше по сравнению с этой более простой версией.