gnu paralelo: reenvía todo el stdin a todos los procesos

gnu paralelo: reenvía todo el stdin a todos los procesos

Estoy tratando de procesar la entrada de diferentes maneras en paralelo, escribiendo las líneas resultantes a medida que aparecen. Mi enfoque actual es el siguiente:

# process_parallel.sh
read input
parallel --colsep ' ' --linebuffer 'echo $input | {}' \
 ::: 'python process1.py' ./process2.sh ./process3

El contexto se reduce a algo como esto:

(sleep 1; echo "short input arriving late") | ./process_parallel.sh | ./collate_results.sh

Lo anterior funciona pero tiene un inconveniente importante: los procesos no se inician hasta que se haya leído la entrada. Quiero iniciarlos de inmediato, ya que eso puede llevar un tiempo, luego conectar en paralelo su entrada estándar completa a cada uno de ellos.

¿Cómo logro eso?

Respuesta1

Se ha trabajado bastante en GNU Parallel para que no inicie un nuevo trabajo a menos que haya datos para ejecutar. Esto se debe a que algunos programas fallan mucho si no reciben ninguna información. Entonces trabajarás en contra del diseño de GNU Parallel.

Para duplicar la entrada puede utilizar teey procesar la sustitución:

cat namedpipe_or_file | tee >(process1) >(process2) >(process3) >/dev/null

Comenzará process1, process2e process3inmediatamente. Sin embargo, la salida se puede mezclar, por lo que si se debe utilizar la salida, se debe redirigir a archivos diferentes:

cat namedpipe_or_file | tee >(process1 > out1) >(process2 > out2) >(process3 > out3) >/dev/null

Respuesta2

Tenga dos scripts contenedores: primero, modifique process_parallel.sh para que cada uno de los procesos reciba instrucciones de leer su entrada, de tres archivos, digamos archivo1, archivo2, archivo3.

Ahora escriba un segundo script contenedor que envíe en paralelo su entrada estándar a los tres archivos, algo como:

  #!/bins/bash
  #parallelise input
  # let's call this file parallelise
  parallel -j 3 -- "echo $1 > file1" "echo $1 > file2" "echo $1 file3"

Ahora empiezas tus cosas con:

  ./process_parallel_sh; cat InputFile | parallelise; 

Respuesta3

Paralelo tiene una --teeopción que se puede utilizar así:

(sleep 1; echo "short input arriving late") |\
parallel --colsep ' ' --linebuffer --pipe --tee ::: 'python process1.py' ./process2.sh ./process3 |\
./collate_results.sh

VerGNU "paralelo" cómo lograr el comportamiento en T

información relacionada