Выполнять команды с переменной цикла параллельно, не более N одновременно

У меня три тысячи файлов на сервере. Я могу получить по одному через вызов REST API. Я написал команду для получения этих файлов. Это работает отлично, но для моего времени входа в систему после примерно 200 загрузок.

Я хотел бы загружать все эти файлы параллельно, а не последовательно. В идеале я хотел бы получить файлы 1-200 одновременно, 200-400 одновременно, 400-600 одновременно.... и т. Д.

Итак, моя попытка:

FOR /L %i in (0,1,200) do wget --no-check-certificate --content-disposition  --load-cookies cookies.txt \ -p https://username:password@website.APICall.com/download/%i

Как я могу преобразовать это в параллельный вызов, который я хочу создать?

Благодарю.

4 ответа

С установленными Cygwin и GNU Parallel вы можете скачать 3000 файлов с 200 параллельными загрузками, которые выполняются постоянно, используя:

seq 3000 | parallel -j 200 wget --no-check-certificate --content-disposition  --load-cookies cookies.txt -p https://username:password@website.APICall.com/download/{}

Альтернатива GNU parallel метод хорош xargs с -P опция:

$ seq 3000 | xargs -i '{}' -n 1 -P 200 wget <url_start>{}<url_end>

Я сомневаюсь, что ваша команда работает, потому что переменная итератора, насколько я знаю, требует двойного процента, т.е. %i должно быть %%i ,

Что касается распараллеливания, вы можете попробовать это:

FOR /L %%i IN (0,1,200) DO ( 
    start wget --no-check-certificate --content-disposition --load-cookies cookies.txt -p "https://username:password@website.APICall.com/download/%%i"
)

Для первых 200 загрузок будет запускаться отдельный процесс (и окно оболочки!) Для каждой загрузки. Это вызовет большую нагрузку на сервер, и я не уверен, что это действительно способ двигаться вперед. Но он делает то, что вы просили.

Изменить: приведенное выше примечание относится к использованию команды в .bat файл, если вы выполняете это непосредственно в оболочке, достаточно одного процента.

Не проходите через стычку с Cygwin; Попытка превратить Windows в UNIX усугубляет проблемы и добавляет слои зависимостей. Используйте PowerShell.

Если вы можете загрузить 200 файлов до истечения времени ожидания, разбейте его на три задания:

invoke-command -asjob -scriptblock {$files = @(1..200);$files | foreach-object{ & wget --no-check-certificate --content-disposition  --load-cookies cookies.txt -p https://username:password@website.APICall.com/download/$_}};
invoke-command -asjob -scriptblock {$files = @(201..400);$files | foreach-object{ & wget --no-check-certificate --content-disposition  --load-cookies cookies.txt -p https://username:password@website.APICall.com/download/$_}};
invoke-command -asjob -scriptblock {$files = @(601..400);$files | foreach-object{ & wget --no-check-certificate --content-disposition  --load-cookies cookies.txt -p https://username:password@website.APICall.com/download/$_}};

Или получите Invoke-Parallel и используйте его так:

$filenames = @(1..600);    
invoke-parallel -InputObject $servers -throttle 200 -runspaceTimeout 30 -ScriptBlock { & wget --no-check-certificate --content-disposition  --load-cookies cookies.txt -p https://username:password@website.APICall.com/download/$_}

Другой (и, вероятно, лучший) вариант - использовать invoke-webrequest, но я не знаю, будет ли он работать здесь с вашими требованиями к файлам cookie.

Отказ от ответственности: работа из памяти, поскольку у меня нет Windows или вашего URL, доступного в данный момент.

Другие вопросы по тегам