2011-01-11 8 views
6

Dada la siguiente entrada de la entrada estándar ejemplo:¿Es posible distribuir STDIN en procesos paralelos?

foo 
bar bar 
baz 
=== 
qux 
bla 
=== 
def 
zzz yyy 

¿Es posible dividirlo en el delimitador (en este caso '===') y se alimentan sobre la entrada estándar a un comando que se ejecuta en paralelo?

Así la entrada ejemplo anterior se traduciría en 3 procesos paralelos (por ejemplo un comando llamado do.sh) donde cada instancia de recepción de una parte de los datos sobre STDIN, como este:

do.sh (instancia 1) recibe este sobre STDIN:

foo 
bar bar 
baz 

do.sh (ejemplo 2) recibe este sobre STDIN:

qux 
bla 

do.sh (ejemplo 3) recibe esta por stdin:

def 
zzz yyy 

supongo que algo como esto es posible usando xargs o paralelo GNU, pero no sé cómo.

Respuesta

10

paralelo GNU puede hacerlo desde la versión 20110205.

cat | parallel --pipe --recend '===\n' --rrs do_stuff 
2

En general, no. Una de las razones de esta evaluación es que la lectura de E/S estándar de archivos, en lugar de la terminal, lee bloques de datos - BUFSIZ bytes a la vez, donde BUFSIZ suele ser una potencia de 2 como 512 o superior. Si los datos están en un archivo, un proceso leería todo el archivo mostrado; los demás no verían nada si compartieran la misma descripción de archivo abierto (similar a un descriptor de archivo, pero varios descriptores de archivos pueden compartir la misma descripción de archivo abierto, y podría estar en procesos diferentes), o leería el mismo archivo si no compartieran la misma descripción de archivo abierto.

Por lo tanto, necesita un proceso para leer el archivo que sabe que necesita para parcelar la información a los tres procesos, y necesita saber cómo se conecta a los tres procesos. Es posible que su programa de distribuidor ejecute los tres procesos y escriba en sus entradas de tubería separadas. O podría ser que el distribuidor se conecte a tres enchufes y escriba en los diferentes enchufes.

Su ejemplo no muestra/describe lo que sucedería si hubiera 37 secciones separadas por el marcador.

Tengo un programa de cerveza casera llamada tpipe que es como el comando Unix tee, pero escribe una copia de (todos) su entrada estándar a cada uno de los procesos, y la salida estándar demasiado por defecto. Esta podría ser una base adecuada para lo que necesita (al menos cubre la parte de administración de procesos). Contáctame si quieres una copia - mira mi perfil.


Si está utilizando Bash, puede utilizar regularmente tee sustituyendo proceso para simular tpipe. Vea esto article para una ilustración de cómo.

Ver también SF 96245 para otra versión de la misma información - además de un enlace a un programa llamado pee que es bastante similar a tpipe (la misma idea básica, ligeramente diferente aplicación en varios aspectos).

+0

¿Cómo se diferencia 'tpipe' de' pee'? –

+0

Escribí tpipe y no había oído hablar de pis antes. Pero no me sorprende que alguien más tenga el mismo requisito básico y lo haya implementado. No estoy seguro de si puedes adivinar lo difícil que es buscar 'pipí' a través de Google (incluso 'site: gnu.org pis' se convierte en spam). Entonces, sin una URL para el software, no puedo comparar ni contrastar. –

+0

http://serverfault.com/questions/96245/linux-debian-what-does-pee-in-moreutils-do muestra 'pee' en uso y muestra cómo no se necesita' pee' en 'bash':' archivo de gato | tee> (command1> out1)> (command2> out2) ' –

1

Puede hacerlo usando named pipes. Las tuberías con nombre le permiten tratar las tuberías estándar como archivos. Puede tener varias canalizaciones con nombre y que sus otros programas las procesen.

No estoy muy familiarizado con los tubos con nombre, pero los he usado de vez en cuando en situaciones como esta.

Cuestiones relacionadas