Выполнять команды с переменной цикла параллельно, не более 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/{}
Я сомневаюсь, что ваша команда работает, потому что переменная итератора, насколько я знаю, требует двойного процента, т.е. %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, доступного в данный момент.