Eu tenho um script bash que se parece com isso:
#!/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
Mas processar cada linha até que o comando seja concluído e passar para a próxima consome muito tempo. Quero processar, por exemplo, 20 linhas de uma só vez e, quando terminar, outras 20 linhas serão processadas.
Pensei wget LINK1 >/dev/null 2>&1 &
em enviar o comando para segundo plano e continuar, mas existem 4000 linhas aqui, isso significa que terei problemas de desempenho, sem mencionar que estou limitado em quantos processos devo iniciar ao mesmo tempo, para que isso não seja uma boa ideia. idéia.
Uma solução em que estou pensando agora é verificar se um dos comandos ainda está em execução ou não, por exemplo, após 20 linhas, posso adicionar este loop:
while [ $(ps -ef | grep KEYWORD | grep -v grep | wc -l) -gt 0 ]; do
sleep 1
done
É claro que, neste caso, precisarei anexar e ao final da linha! Mas sinto que esse não é o caminho certo para fazê-lo.
Então, como eu realmente agrupo cada 20 linhas e espero que elas terminem antes de passar para as próximas 20 linhas, esse script é gerado dinamicamente para que eu possa fazer qualquer matemática que eu quiser enquanto estiver sendo gerado, mas NÃO PRECISA use wget, era apenas um exemplo, então qualquer solução específica do wget não me ajudaria.
wait
é a resposta certa aqui, mas vocêwhile [ $(ps …
seria muito melhor escritowhile pkill -0 $KEYWORD…
- usando proctools ... ou seja, por razões legítimas para verificar se um processo com um nome específico ainda está em execução.Respostas:
Use o
wait
built-in:Para o exemplo acima, 4 processos
process1
...process4
seriam iniciados em segundo plano e o shell aguardaria até que eles fossem concluídos antes de iniciar o próximo conjunto.No manual GNU :
fonte
i=0; waitevery=4; for link in "${links[@]}"; do wget "$link" & (( i++%waitevery==0 )) && wait; done >/dev/null 2>&1
Veja paralelo . Sua sintaxe é semelhante a
xargs
, mas executa os comandos em paralelo.fonte
wait
, pois cuida de iniciar novos trabalhos à medida que os antigos são concluídos, em vez de aguardar a conclusão de um lote inteiro antes de iniciar o próximo.cat list_of_links.txt | parallel -j 4 wget {}
que manterá quatrowget
segundos em execução por vez.parallel
.parallel --jobs 4 < list_of_commands.sh
, em que list_of_commands.sh é um arquivo com um único comando (por exemplowget LINK1
, observe sem o&
) em todas as linhas. Pode ser necessário fazerCTRL+Z
ebg
depois deixá-lo em execução em segundo plano.De fato,
xargs
pode executar comandos em paralelo para você. Existe uma-P max_procs
opção de linha de comando especial para isso. Vejaman xargs
.fonte
Você pode executar 20 processos e usar o comando:
Seu script aguardará e continuará quando todos os seus trabalhos em segundo plano forem concluídos.
fonte