Gerando múltiplos alertas paralelos e armazenando resultados em uma matriz bash para ser bem impresso quando todos os desejos são feitos | shelleyness.com
Questão Gerando múltiplos alertas paralelos e armazenando resultados em uma matriz bash para ser bem impresso quando todos os desejos são feitos
Eu tenho uma longa lista de URLs no meu próprio site listado em um arquivo de texto separado de retorno de carro. Então, por exemplo:
http: /www.mysite.com/url1.html
http: /www.mysite.com/url2.html
http: /www.mysite.com/url3.html
Eu preciso gerar um número de wgets paralelos para acertar cada URL duas vezes, verificar e recuperar um cabeçalho específico e, em seguida, salvar os resultados em uma matriz que eu quero imprimir em um relatório legal.
Eu tenho parte do que eu quero usando o seguinte comando xargs:
A questão é como executar este comando duas vezes e armazenar o seguinte:
O hit do URL
O primeiro resultado do grep contra o cabeçalho do cache
O 2º resultado do grep contra o cabeçalho do Cache
Então a saída deve ser algo como:
Ordenar que os URLs sejam exibidos não é necessariamente uma preocupação, desde que os cabeçalhos estejam associados ao URL.
Devido ao número de URLs que preciso atingir vários URLs em paralelo, não em série, caso contrário, será muito demorado.
O truque é como obter vários alertas paralelos e armazenar os resultados de maneira significativa. Eu não sou casado com o uso de uma matriz se existe uma maneira mais lógica de fazer isso (talvez escrevendo em um arquivo de log?)
Algum guru bash tem alguma sugestão de como eu poderia proceder?
Suas entradas são realmente separadas por retornos de carro (\r), não novas linhas (\n) ou estilo windows (\r\n)? Este é um arquivo de um velho Mac? - terdon
Você pode querer experimentar o gnu paralelo. em particular, a manpage menciona que "GNU parallel garante que a saída dos comandos é a mesma saída que você obteria se tivesse executado os comandos sequencialmente." - kampu
Faça um pequeno script que faça a coisa certa com um único URL (baseado no código de terdon):
Em seguida, execute este script em paralelo (digamos, 500 jobs de cada vez) usando o GNU Parallel:
O GNU Parallel fará com que a saída de dois processos nunca seja misturada - uma garantia que xargs não oferece.
Você pode encontrar mais sobre o GNU Parallel em: http://www.gnu.org/s/parallel/
Você pode instalar o GNU Parallel em apenas 10 segundos com:
Assista ao vídeo de introdução http://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Ah, sim, deveria ter pensado nisso, +1. - terdon
Uma solução trivial seria registrar a saída de cada um dos wget comandos para um arquivo separado e usando cat para mesclá-los depois.
Eu tenho 22.000 URLs. Eu suponho que eu poderia criar 22.000 arquivos de texto e, em seguida, tentar mesclar e excluí-los depois, mas devo admitir que não gosto muito de gerar todo esse I / O. - Brad
22.000 arquivos não são muito no meu livro, mas eu acho que vem com o território. time for i in {1..22000}; do echo "Number $i" > $i; done - 1,7 segundos Removendo-os: Menos de um segundo. - l0b0
Assumirei que seu arquivo é de nova linha, não de retorno de carro separado, porque o comando que você dá não funcionará com um \r arquivo separado.
Se o seu arquivo é usando \r ao invés de \n para fins de linha, altere-o para usar \n executando isto:
Se você estiver usando o estilo do Windows (\r\n) terminações de linha, use isto:
Agora, depois de ter seu arquivo no formato Unix, se você não se importa que seus trabalhos não sejam executados em paralelo, você pode fazer algo assim:
ATUALIZAR em resposta ao seu comentário:
Se você tem 22.000 URLs, posso realmente entender por que você quer fazer isso em paralelo. Uma coisa que você pode tentar é criar arquivos tmp:
Existem duas sub-unidades lançadas lá, a primeira (while ... < urls.txt) é justthere para suprimir mensagens de conclusão. O segundo (( echo "=== ... ) > mktemp urltmpXXX) está lá para coletar todas as saídas de um determinado URL em um arquivo.
O script acima criará 22.000 arquivos tmp chamados urltmpXXX onde o XXX é substituído por tantos caracteres aleatórios. Como os arquivos tmp terão 6 linhas de texto quando todos tiverem terminado, você poderá monitorar (e, opcionalmente, excluir os arquivos) com este comando:
Agora, o outro problema é que isso vai lançar 22000 empregos de uma só vez. Dependendo do seu sistema, isso pode ou não ser um problema. Uma maneira de contornar isso é split seu arquivo de entrada e, em seguida, execute o loop acima uma vez para cada arquivo.
Obrigado, eu já tenho um script que é executado em série. I.E. um URL de cada vez. A questão é que temos 22.000 URLs para acertar. Correndo embora eles em série leva muito tempo. Eu preciso de uma solução que seja executada em paralelo para reduzir o tempo de execução do script. O problema é que, quando você executa em paralelo, como você registra os resultados de uma forma que pode ser gerada em um relatório sensato depois? - Brad
@Brad Atualizei minha resposta com uma maneira (talvez absurdamente complicada) de executá-la em paralelo. - terdon
Na verdade, isso deixou meu servidor de joelhos. Opa! Eu acho que eu preciso quebrar isso / acelerá-lo de alguma forma. - Brad
@Brad sim, eu avisei você :). Tente dividir o arquivo em, digamos, 100 trechos de linha: split -l 100 urls.txt, em seguida, execute o loop em cada arquivo: for file in x*; do (while read url; do ... ;done < $file); done. Aqui, <$file substitui <urls.txt. - terdon
Como mudar o ícone do ponteiro do mouse no Xfce Debian 7 Wheezy? comando netsh para bloquear o URL do firewall Como configurar o WOL através da WAN? Meu laptop não inicializa depois de adicionar RAM Sem permissões de leitura / gravação de cartão SD no Windows 7 Posso conectar um cabo ADSL a um roteador com um conversor RJ11 para RJ45? Erro ao validar para cabeçalhos do kernel do Ubuntu 12.10