Pasar argumentos a un programa interactivo de forma no interactiva

113

Tengo un script bash que emplea el readcomando para leer argumentos a comandos de forma interactiva, por ejemplo, opciones sí / no. ¿Hay alguna forma de llamar a este script en un script no interactivo pasando valores de opción predeterminados como argumentos?

No es solo una opción que tengo que pasar al script interactivo.

sidharth sharma
fuente
2
Si está leyendo desde stdin, puede canalizar su entrada
lc.
4
Como esta pregunta tiene muchos duplicados, vale la pena señalar que no importa en qué idioma esté escrito el programa interactivo. Podría ser un programa en C que lee la entrada estándar, o una aplicación Erlang, o lo que sea. Hay algo que se ejecuta desde la línea de comandos y exige de manera desagradable una entrada interactiva, y le gustaría automatizarlo.
tripleee
Por supuesto, si tiene control sobre la aplicación desagradable, vuelva a escribirla para que pueda leer las respuestas de forma no interactiva (a través de un archivo de configuración, opciones de línea de comandos o lo que sea). Esto es mucho más confiable y robusto contra el cambio de orden o redacción de preguntas interactivas.
tripleee

Respuestas:

46

Para tareas más complejas existe expect( http://en.wikipedia.org/wiki/Expect ). Básicamente, simula a un usuario, puede codificar un script sobre cómo reaccionar a salidas de programas específicos y cosas relacionadas.

Esto también funciona en casos como el sshque prohíbe canalizar contraseñas.

Dani Gehtdichnixan
fuente
8
... Aunque la solución adecuada en el caso de SSH es cambiar a la autenticación de clave pública.
tripleee
154

Muchas maneras

canalice su entrada

echo "yes
no
maybe" | your_program

redirigir desde un archivo

your_program < answers.txt

use un documento aquí (esto puede ser muy legible)

your_program << ANSWERS
yes
no
maybe
ANSWERS

usa una cadena aquí

your_program <<< $'yes\nno\nmaybe\n'
Glenn Jackman
fuente
5
Cabe señalar que esto solo funciona si el programa lee la entrada estándar. Algunos programas hacen todo lo posible para leer, por ejemplo, contraseñas de forma interactiva, incluso cuando la entrada estándar es una tubería. Para las contraseñas, esto tiene sentido por razones de seguridad; aunque algunos programas interactivos están simplemente mal diseñados.
tripleee
@tripleee En la línea de lo que dijo, ¿cómo lee un script las contraseñas que no se ven afectadas por stdin? Sé que puede usar readpara agarrar stdin, ¿qué función puede usar para hacer lo que describió?
flow2k
En ese caso, necesita ver si el programa con el que está tratando de interactuar tiene una forma especial de enviarle la entrada (por ejemplo, sshpass, ssh-agent), o use esperar para escribir la interacción.
Glenn Jackman
2
Lo que hacen programas como Expect es ejecutar el cliente bajo un pseudo-tty donde el cliente ve como si hubiera un usuario con una terminal y un teclado en el otro extremo. No puedes hacer eso con una pipa normal.
tripleee
Noticia importante. Esto no funciona si agregamos espacios a los comandos proporcionados.
71GA
13

Puede poner los datos en un archivo y redirigirlo así:

$ cat file.sh
#!/bin/bash

read x
read y
echo $x
echo $y

Datos para el guión:

$ cat data.txt
2
3

Ejecutando el script:

$ file.sh < data.txt
2
3
Gurú
fuente
7

Solo quiero agregar una forma más. Lo encontré en otro lugar, y es bastante simple. Digamos que quiero pasar sí a todas las solicitudes en la línea de comando para un comando "execute_command", luego simplemente enviaría sí.

yes | execute_command

Esto usará sí como respuesta a todas las preguntas de sí / no.


fuente
1

También puede usar printf para canalizar la entrada a su script.

var=val
printf "yes\nno\nmaybe\n$var\n" | ./your_script.sh
spanchan
fuente
0

otra alternativa puede ser

echo "something" | tee /path/to/file

El comando tee imprime la entrada que recibe en la pantalla y la guarda en un archivo al mismo tiempo.

Prafulla Kumar Sahu
fuente