2010-01-02 19 views
5

Estoy tratando de leer de stdin varias veces en un script de shell, sin suerte. La intención es leer primero una lista de archivos (que se leen desde la tubería stdin), y luego leer dos veces más para obtener dos cadenas de forma interactiva. (Lo que intento hacer es leer una lista de archivos para adjuntar en un correo electrónico, luego el asunto y finalmente el cuerpo del correo electrónico).leyendo stdin varias veces en bash

Hasta ahora tengo esto:

photos=($(< /dev/stdin)) 

echo "Enter message subject" 
subject=$(< /dev/stdin) 

echo "Enter message body" 
body=$(< /dev/stdin) 

(además de la comprobación de errores de código que omito para succintness)

Sin embargo, esto se vuelve un asunto vacío y el cuerpo presumiblemente porque el segundo y tercer redirecciones consiguen EOF .

He estado tratando de cerrar y volver a abrir stdin con < & - y cosas así, pero parece que no funciona de esa manera.

Incluso intenté usar un separador para la lista de archivos, utilizando un ciclo "while; read line" y salí del bucle cuando se detectó el separador. Pero eso tampoco funcionó (??).

Alguna idea de cómo construir algo como esto?

Respuesta

5

Así que lo que terminó haciendo se basa en la respuesta de EZPZ y esto doc: http://www.faqs.org/docs/abs/HTML/io-redirection.html Básicamente me pedirá el campo por primera vez de/dev/tty, y luego lea stdin, usando el truco de duplicar y cerrar:

# close stdin after dup'ing it to FD 6 
exec 6<&0 

# open /dev/tty as stdin 
exec 0</dev/tty 

# now read the fields 
echo "Enter message subject" 
read subject 
echo "Enter message body" 
read body 

# done reading interactively; now read from the pipe 
exec 0<&6 6<&- 
fotos=($(< /dev/stdin)) 

¡Gracias!

2

Dado que es posible que tenga una cantidad variable de fotos, ¿por qué no solicita primero los campos conocidos y luego lee "todo lo demás". Es mucho más fácil que tratar de obtener los últimos dos campos de una longitud desconocida de una manera interactiva.

+0

La razón por la que no funciona para mí es que estoy tratando de usar una tubería para pasar la lista de fotos. Si simplemente leo los campos antes de la lista, las dos primeras fotos en la lista terminan siendo asunto y cuerpo del correo electrónico, que no es lo que quiero. (Por supuesto, podría dictar que el sujeto y el cuerpo se deben pasar en las dos primeras líneas del tubo de entrada, pero eso es demasiado feo para mí). – alvherre

3

Usted debe ser capaz de utilizar read para que solicite el asunto y el cuerpo:

photos=($(< /dev/stdin)) 

read -rp "Enter message subject" subject 

read -rp "Enter message body" body 
+0

Gracias. Eso funciona si estoy ingresando los datos de forma interactiva. Sin embargo, si utilizo una tubería (que es lo que realmente me interesa), no es así. Por ejemplo, estoy tratando de hacer esto: cat/tmp/somephotoids | sed-e 's /\(.*\)/ DSC_ \ 1.jpg /' | sendpics.sh Si bien pude solucionar el problema mediante el corte del paso, he dedicado suficiente tiempo para hacerlo de esta manera que ahora lo considero como una especie de desafío. – alvherre