2009-09-28 24 views
5

Tengo un programa que lee desde la entrada estándar cuando se invoca desde la línea de comando. Normalmente, el usuario ingresaría cierta información, presionar C-d en una nueva línea para señalar el final del archivo, y el programa procesaría el archivo. Luego se volvería a preguntar al usuario, ingresaría más texto y nuevamente presionar C-d para señalar el final del segundo archivo.enviando múltiples archivos desde el script de shell a través de la entrada estándar

Estoy buscando escribir un script de shell que invocará este programa y enviará automáticamente los dos archivos. Me gustaría hacer algo como esto:

$ myprogram < file1.txt < file2.txt 

O

$ myprogam <file1.txt file2.txt 

¿Alguna sugerencia? Estoy usando el shell bash en Linux.

+0

¿Cómo indica el usuario el final de todos los archivos? Dos control-D en una fila? El diseño estándar para los programas de Unix es "leer archivos nombrados en la línea de comandos, si no hay tales archivos, procesar la entrada estándar". Si adoptas ese diseño, no hay problemas; solo invocas 'myprogram file1.txt file2.txt'. –

Respuesta

3

Obviamente puede utilizar cat enviar dos archivos en una entrada estándar de programas, pero esto probablemente no es lo que quiere:

$ cat file1.txt file2.txt | myprogram 

En el caso anterior myprogram no sería capaz de decir dónde file1.txt extremos y file2.txt comienza, a menos que tuvieran un formato específico y estaba viendo la transmisión para cierto formato que significaba el final o el comienzo de un archivo.

No hay una manera estándar de enviar múltiples flujos a la entrada estándar. Básicamente, solo hay una única transmisión entrando en la entrada estándar.

Probablemente estructure el script para que acepte varios argumentos en la línea de comandos y los abra internamente y los procese de a uno por vez. Es decir, que le llaman así:

$ myprogram file1.txt file2.txt 
+0

tal vez hay una manera de decir: $ cat archivo1.txt "EOF" archivo2.txt y luego sabría que se trata de dos archivos separados? –

+0

No, no hay una forma de enviar EOF así; ver mis comentarios a la respuesta de Pavel Shved. –

0

Jonathan Leffler dice en su comentario, que mi solución es incorrecta. Tal vez lo sea De hecho, no lo he revisado a fondo. Pero déjalo aquí solo por información que es una respuesta incorrecta, al menos.


Bash puede repetir un carácter de control con su comando echo. EOF es C-d, como ya ha señalado, así que vamos a utilizar un subnivel:

$ (cat file1.txt ; echo -e '\cD' ; cat file2.txt) | myprogram 

Esto ejecutar comandos dentro de los paréntesis y el tubo de salida de todos ellos como si se tratara de un programa separado.

Si no está seguro de que las tuberías correctamente, intente esto:

$ (echo "Hello" ; echo -e '\cD' ; echo "bash") | tee 
+1

El control-D es interceptado por el controlador del terminal y lo envía a enviar datos pendientes, sin caracteres, si no hay ninguno pendiente. Por lo tanto, el programa obtiene una lectura de cero bytes, que indica EOF. Hacer eco de los caracteres de control literal D en la tubería no simula esto, no hay un controlador de terminal para ayudar. Ahí es donde entra 'expect '- usa pseudo-ttys para emular terminales. –

2

¿Tiene que ser de 1 invocación? Si no:

for file in file1 file2 file3; do myprogram < $file; done 
0

He escrito un programa simple de Python para simular el comportamiento del programa que describes. Como mínimo, esto nos coloca a todos en la posición de hablar sobre lo mismo en lugar de asumir cómo funciona su programa. (Por supuesto, si su programa no funciona de la manera que lo estoy describiendo aquí, por favor corríjanme.)

#!/usr/bin/python 

def read_a_file(): 
    print('Type the contents of a file now.') 
    while True: 
     try: 
      s = raw_input('>') 
     except EOFError: 
      break 

read_a_file() 
read_a_file() 
print('We have now read two files. Quitting.') 

Puede ejecutar esta secuencia de comandos, escriba el contenido del primer archivo, pulse Ctrl-D, escriba el contenido del segundo archivo, pulse CTRL-D, y el programa se cierra. Este parece ser el comportamiento que describes.

Mi primer pensamiento fue usar esperar, como sugirió el caos. Sin embargo, no encuentro ningún soporte en esperar para conectar el contenido de un archivo a un proceso. (Supongo que el contenido de los archivos es diferente cada vez. Si son lo mismo, entonces esperaría que funcione, simplemente colocando el contenido de los archivos en el script esperado.)

Debo señalar que estoy de ninguna manera un experto esperado; puede haber una manera de hacer esto que no sea obvia para mí.

Mi segundo pensamiento fue escribir una secuencia de comandos de Python que lanzara su programa y le diera el contenido de los archivos y los caracteres EOF. Sin embargo, los comentarios de Jonathan Leffler me hicieron pensar que repetir los caracteres EOF no funcionaría.

Mi tercer pensamiento es bastante maldito kludgy. Podría escribir un script que cree un script esperado al conectar el contenido de los archivos en el script esperado y luego ejecutar el script esperado. Sospecho que eso funcionaría.

Cuestiones relacionadas