Hacer que el script de bash responda a las preguntas interactivas [duplicado]

109

¿Es posible que un script bash maneje automáticamente las solicitudes que normalmente se le presentarán al usuario con acciones predeterminadas? Actualmente estoy usando un script bash para llamar a una herramienta interna que mostrará mensajes al usuario (solicitando Y / N) para completar acciones, sin embargo, el script que estoy escribiendo debe ser completamente "sin intervención", por lo que Necesito una forma de enviar Y|Nal indicador para permitir que el programa continúe ejecutándose. es posible?

TJ L
fuente
esto no es "autocompletar" ... como dice @unwind, es "automatización"
benzaita
3
Ejemplo de uso yespara hacer esto: unix.stackexchange.com/questions/47344/…
Droogans

Respuestas:

65

Esto no es "autocompletar", es automatización. Una herramienta común para estas cosas se llama Expect .

También puede salirse con la suya con solo canalizar la entrada de yes.

relajarse
fuente
3
Desafortunadamente, no puedo usar la expectativa ya que hay estrictos requisitos de espacio en el sistema que ejecuta esto, por lo que no puedo agregar paquetes adicionales, pero la canalización yeshizo el truco, afortunadamente, todas las indicaciones solo requerían una 'y' de todos modos. Gracias.
TJ L
Sin embargo, Yes | commandpuede que no funcione siempre. Si es solo para fines de instalación, entonces el uso -yes una opción mejor y preferida.
Umesh Kaushik
169

Un simple

echo "Y Y N N Y N Y Y N" | ./your_script

Esto le permite pasar cualquier secuencia de "Y" o "N" a su secuencia de comandos.

Loïc Février
fuente
3
Si Ntuviera que enviar alguno , habría usado este método, pero solo necesitaba Y, así que seguí yes. Lástima que no pueda aceptar dos respuestas, ya que ambas son correctas.
TJ L
3
;) Bueno, si alguna vez necesitas enviar algo N, ahora tienes una buena manera de hacerlo.
Loïc Février
2
Esto no funciona para mí; los espacios no cuentan como nuevas líneas --- si, por ejemplo, hago eco de "Y N", entonces da la cadena "Y N"como entrada al primer mensaje y se cuelga en el segundo mensaje esperando que lo complete. Intenté cambiar los espacios a nuevas líneas, pero eso tampoco funcionó, aún así le di una cadena literal al indicador.
temporary_user_name
52
intente usar printf 'y\ny\ny\n' | ./your_script. De esta manera, está insertando manualmente la nueva línea para cada entrada esperada.
Majid
8
printf '%s\n' Y Y N N Y N Y Y Ncoloca nuevas líneas entre los elementos, pero sin necesidad de una cadena de formato grande.
Charles Duffy
16

Encontré que la mejor manera de enviar entradas es usar cat y un archivo de texto para pasar cualquier entrada que necesites.

cat "input.txt" | ./Script.sh
Alex
fuente
Expect no funcionó como se esperaba para mí. Esta es la mejor y más simple respuesta a esta pregunta.
cloudxix
12

Si solo tiene Y para enviar:

$> yes Y |./your_script

Si solo tiene N para enviar:

$> yes N |./your_script
douardo
fuente
9

En mi situación, necesitaba responder algunas preguntas sin S o N pero con texto o en blanco. Encontré que la mejor manera de hacer esto en mi situación era crear un archivo shellscript. En mi caso lo llamé autocomplete.sh

Necesitaba responder algunas preguntas para un exportador de esquemas de doctrina, por lo que mi archivo se veía así.

- Este es solo un ejemplo -

php vendor/bin/mysql-workbench-schema-export mysqlworkbenchfile.mwb ./doctrine << EOF
`#Export to Doctrine Annotation Format`                                     1
`#Would you like to change the setup configuration before exporting`        y
`#Log to console`                                                           y
`#Log file`                                                                 testing.log
`#Filename [%entity%.%extension%]`
`#Indentation [4]`
`#Use tabs [no]`
`#Eol delimeter (win, unix) [win]`
`#Backup existing file [yes]`
`#Add generator info as comment [yes]`
`#Skip plural name checking [no]`
`#Use logged storage [no]`
`#Sort tables and views [yes]`
`#Export only table categorized []`
`#Enhance many to many detection [yes]`
`#Skip many to many tables [yes]`
`#Bundle namespace []`
`#Entity namespace []`
`#Repository namespace []`
`#Use automatic repository [yes]`
`#Skip column with relation [no]`
`#Related var name format [%name%%related%]`
`#Nullable attribute (auto, always) [auto]`
`#Generated value strategy (auto, identity, sequence, table, none) [auto]`
`#Default cascade (persist, remove, detach, merge, all, refresh, ) [no]`
`#Use annotation prefix [ORM\]`
`#Skip getter and setter [no]`
`#Generate entity serialization [yes]`
`#Generate extendable entity [no]`                                          y
`#Quote identifier strategy (auto, always, none) [auto]`
`#Extends class []`
`#Property typehint [no]`
EOF

Lo que me gusta de esta estrategia es que puedes comentar cuáles son tus respuestas y usando EOF una línea en blanco es solo eso (la respuesta predeterminada). Resulta, por cierto, que esta herramienta de exportación tiene su propia contraparte JSON para responder estas preguntas, pero lo descubrí después de hacer esto =).

para ejecutar el script simplemente esté en el directorio que desee y ejecútelo 'sh autocomplete.sh'en la terminal.

En resumen, al usar << EOL & EOF en combinación con las líneas de retorno , puede responder a cada pregunta del mensaje según sea necesario. Cada nueva línea es una nueva respuesta.

Mi ejemplo solo muestra cómo se puede hacer esto con comentarios también usando el carácter `para que recuerde lo que es cada paso.

Tenga en cuenta que la otra ventaja de este método es que puede responder con más que solo Y o N ... ¡de hecho, puede responder con espacios en blanco!

Espero que esto ayude a alguien.

José Astrahan
fuente
4

Hay una utilidad incorporada especial para esto: ' '.

Para responder a todas las preguntas con la misma respuesta, puede ejecutar

yes [answer] |./your_script

O puede ponerlo dentro de su guión para tener una respuesta específica a cada pregunta

Asaf Pinhassi
fuente
¿Cómo puedo hacer eso dentro del script? Quiero especificar diferentes respuestas para cada pregunta
Sengo