
Eu tenho um script de shell bash no qual canalizo alguns dados por cerca de 5 ou 6 programas diferentes e, em seguida, os resultados finais em um arquivo delimitado por tabulações.
Em seguida, faço o mesmo novamente para um conjunto de dados semelhante separado e envio para um segundo arquivo.
Em seguida, ambos os arquivos são inseridos em outro programa para análise comparativa. por exemplo, para simplificar
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv
AnalysisProg -i Data1res.csv Data2res.csv
Minha pergunta é: como posso executar a etapa 1 e a etapa 2 ao mesmo tempo (por exemplo, usando &), mas apenas iniciar a etapa 3 (AnalysisProg) quando ambas estiverem concluídas?
THX
ps AnalysisProg não funcionará em um stream ou fifo.
Responder1
Usar wait
. Por exemplo:
Data1 ... > Data1Res.csv &
Data2 ... > Data2Res.csv &
wait
AnalysisProg
vai:
- execute os pipes Data1 e Data2 como trabalhos em segundo plano
- espere os dois terminarem
- execute AnalysisProg.
Veja, por exemplo,essa questão.
Responder2
A resposta do cxw é sem dúvida a solução preferível, se você tiver apenas 2 arquivos. Se os 2 arquivos forem apenas exemplos e você realmente tiver 10.000 arquivos, a solução '&' não funcionará, pois sobrecarregará seu servidor. Para isso você precisa de uma ferramenta como o GNU Parallel:
ls Data* | parallel 'cat {} | this | that |theother | grep |sed | awk |whatever > {}res.csv
AnalysisProg -i *res.csv
Para saber mais sobre o GNU Paralelo:
- Assista ao vídeo de introdução para uma introdução rápida: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
- Percorra o tutorial (man paralelo_tutorial). Sua linha de comando vai adorar você por isso.
Responder3
Uma maneira de fazer isso pode ser algo como:
AnalysisProg <<PREPROCESS /dev/stdin
$(
{ process1=$( pipe | line | 1 >&2 & echo $! )
process2=$( pipe | line | 2 >&2 & echo $! )
while ps -p $process1 $process2 >/dev/null; do
sleep 1
done
} 2>&1
)
#END
PREPROCESS
Dessa forma, você coloca em segundo plano ambos os pipelines, mas ainda espera que eles terminem a execução antes de combinar sua saída em stdin, que é avaliado em um documento aqui e entregue ao AnalysisProg. Se você pode usarwait
isso é ainda melhor do que owhile ps
loop, mas, dependendo do shell,wait
pode objetar se você instruí-lo a aguardar um processo quenão é filho do shell atual.
Observe também que o método acima agrupará a saída - portanto, ambos os processos serão gravados ao mesmo tempo. Se você quiser separá-los ou anexá-los um ao outro, poderá fazer:
AnalysisProg 3<<PREPROCESS /dev/fd/3 /dev/stderr
$(
process1=$(... >&2 ...) 2>/dev/fd/3
...
} 3>/dev/fd/3 2>/dev/stderr
)
Já demonstrei esses conceitos antes. Provavelmente as melhores demos sãoaquieaqui.
Responder4
Tente usar isso.
rm -f Data1Res.csv
rm -f Data2Res.csv
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv &
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv &
while true
do
ps aux | grep -v grep | grep -i -E 'Data1Res.csv|Data2Res.csv' &> /dev/null
if [ $? -ne 0 ]
then
AnalysisProg -i Data1res.csv Data2res.csv
exit 0
fi
done