
Tengo un script de shell bash en el que canalizo algunos datos a través de aproximadamente 5 o 6 programas diferentes y luego los resultados finales en un archivo delimitado por tabulaciones.
Luego hago lo mismo nuevamente para un conjunto de datos similar separado y lo envío a un segundo archivo.
Luego, ambos archivos se ingresan en otro programa para su análisis comparativo. por ejemplo, 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
Mi pregunta es: ¿cómo puedo hacer que el paso 1 y el paso 2 se ejecuten al mismo tiempo (por ejemplo, usando &) pero solo inicie el paso 3 (AnalysisProg) cuando ambos estén completos?
Gracias
ps AnalysisProg no funcionará en una secuencia o quince.
Respuesta1
Usar wait
. Por ejemplo:
Data1 ... > Data1Res.csv &
Data2 ... > Data2Res.csv &
wait
AnalysisProg
voluntad:
- ejecutar las canalizaciones Data1 y Data2 como trabajos en segundo plano
- espera a que ambos terminen
- ejecute AnalysisProg.
Ver, por ejemplo,esta pregunta.
Respuesta2
La respuesta de cxw es sin duda la solución preferible, si solo tiene 2 archivos. Si los 2 archivos son solo ejemplos y en realidad tiene 10000 archivos, entonces la solución '&' no funcionará, ya que sobrecargará su servidor. Para eso necesitas una herramienta como GNU Parallel:
ls Data* | parallel 'cat {} | this | that |theother | grep |sed | awk |whatever > {}res.csv
AnalysisProg -i *res.csv
Para obtener más información sobre GNU Parallel:
- Mire el vídeo de introducción para una introducción rápida: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
- Siga el tutorial (man paralelo_tutorial). Tu línea de comando te amará por ello.
Respuesta3
Una forma de hacer esto podría verse así:
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
De esta manera, usted pone en segundo plano ambas canalizaciones pero aún espera a que terminen de ejecutarse antes de combinar su salida en la entrada estándar que se evalúa en un documento aquí y se entrega a AnalysisProg. Si puedes usarwait
esto es incluso mejor que elwhile ps
bucle, pero, dependiendo del caparazón,wait
puede objetar si le indica que espere en un proceso queno es hijo del shell actual.
También tenga en cuenta que el método anterior cotejará la salida, por lo que ambos procesos escribirán a la vez. Si, en cambio, quisiera separarlos o agregarlos uno al otro, posiblemente podría hacer:
AnalysisProg 3<<PREPROCESS /dev/fd/3 /dev/stderr
$(
process1=$(... >&2 ...) 2>/dev/fd/3
...
} 3>/dev/fd/3 2>/dev/stderr
)
He demostrado estos conceptos antes. Probablemente las mejores demostraciones sonaquíyaquí.
Respuesta4
Intenta usar esto.
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