Ingrese automáticamente la entrada en la línea de comando

143

Estoy ejecutando un script que solicita ingresar 'y' en cada operación, estoy buscando una solución como $ ./script < echo 'yyyyyyyyyyyyyy'pasar todas mis entradas de una vez.

NewMrd
fuente
A veces, la -fopción funciona bien con ciertos comandos.
iammilind

Respuestas:

259

Hay un comando creado específicamente para ese caso: yes

$ yes | ./script

Lo que esto hace es conectar la salida de yesa la entrada de ./script. Entonces, cuando ./scriptsolicita la entrada del usuario, en su lugar obtendrá la salida de yes. La salida de yeses un flujo interminable de yseguido por una nueva línea. Básicamente, como si el usuario ingresara ypara cada pregunta de ./script.

Si quiere decir no ( n) en lugar de sí ( y) puede hacerlo así:

$ yes n | ./script

Tenga en cuenta que algunas herramientas tienen la opción de asumir siempre yescomo respuesta. Consulte aquí, por ejemplo: omita el indicador yes / no en 'apt-get upgrade'


Otros métodos para ingresar la entrada:

Si sabe exactamente cuántos yespera su script, puede hacerlo así:

$ printf 'y\ny\ny\n' | ./script

Las líneas nuevas ( \n) son las teclas enter.

Usando en printflugar de yesusted tiene un control de entrada más fino:

$ printf 'yes\nno\nmaybe\n' | ./script

Tenga en cuenta que, en algunos casos excepcionales, el comando no requiere que el usuario presione enter después del carácter. en ese caso, deje las nuevas líneas:

$ printf 'yyy' | ./script

En aras de la integridad también puede utilizar un documento aquí :

$ ./script << EOF
y
y
y
EOF

O si su shell lo admite una cadena aquí :

$ ./script <<< "y
y
y
"

O puede crear un archivo con una entrada por línea:

$ ./script < inputfile

Si el comando es lo suficientemente complejo y los métodos anteriores ya no son suficientes, entonces puede usar esperar .

Aquí hay un ejemplo de un script de espera super simple:

spawn ./script
expect "are you sure?"
send "yes\r"
expect "are you really sure?"
send "YES!\r"
expect eof

Nitpick técnico:

La invocación de comando hipotética que proporcionó en su pregunta no funciona:

$ ./script < echo 'yyyyyyyyyyyyyy'
bash: echo: No such file or directory

Esto se debe a que la gramática del shell permite un operador de redireccionamiento en cualquier lugar de la línea de comando. En lo que respecta al shell, su línea de comando hipotética es la misma que esta línea:

$ ./script 'yyyyyyyyyyyyyy' < echo
bash: echo: No such file or directory

Eso significa ./scriptque se llamará con el argumento 'yyyyyyyyyyyyyy'y el stdin obtendrá información de un archivo llamado echo. Y bash se queja porque el archivo no existe.

lesmana
fuente
1
Me sale un cannot enable tty mode on non tty input. ¿Conocerías una solución para eso?
bmpasini
Cuando intento el printftruco con un runarchivo que necesito para automatizar el proceso de instalación, todo lo que sucede es que recibo un mensaje de error que dice Warning: Tried to connect to session manager, None of the authentication protocols specified are supported, y el script se abre en una nueva terminal y me pide que ingrese mi entrada manualmente como de costumbre. Por cierto, esto está sucediendo en Debian. ¿Alguna sugerencia?
DavidB
Necesito más detalles. Demasiado grande para comentarios. por favor haga una nueva pregunta con todos los detalles. Puedes poner un enlace aquí.
lesmana
nada funciona con 'vagabundo destruir' en centos
Drew
¡Malvado fácil! Funciona en las importaciones de datos SQL de Google Cloud Beta ¡Muy apreciado!
G_Style
11

Usa el comando yes:

yes | script

Extracto de la página del manual:

NAME
       yes - output a string repeatedly until killed

SYNOPSIS
       yes [STRING]...
       yes OPTION

DESCRIPTION
       Repeatedly output a line with all specified STRING(s), or 'y'.
Peter W. Osel
fuente
9

Algunas cosas ( apt-getpor ejemplo) aceptan indicadores especiales para ejecutarse en modo silencioso (y aceptan valores predeterminados). En apt-getel caso, solo pasa una -ybandera. Sin embargo, esto depende completamente de su script.

Si necesita cosas más complicadas, puede ajustar su script en un script de espera. esperar le permite leer la salida y enviar entradas para que pueda hacer cosas bastante complicadas que otras secuencias de comandos no permitirían. Aquí hay uno de los ejemplos de su página de Wikipedia :

# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof
Oli
fuente
Esto no se puede usar con un .shscript de shell, ¿verdad? ¿O hay alguna manera?
Shayan
7

En el script de shell también puede usar el siguiente truco de spawn, esperar y enviar

spawn script.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"

Sin embargo, en el escenario anterior, deberá indicar la frase que espera obtener mientras ejecuta el script. Para obtener más ejemplos, vaya al siguiente enlace

Esperar dentro de Bash

Tarun
fuente
2

De acuerdo, puede que esta no sea una solución muy elegante, pero si escribe sus opciones en un archivo separado y luego lo pasa como una entrada al script, también funcionaría. Entonces, si crea un nuevo archivo con todas sus opciones (llame a este archivo como 'options.in'), entonces puede ejecutar fácilmente su script ./script.sh < options.iny editar / crear diferentes archivos de opciones según corresponda.

Sidhha
fuente
¿Cómo debo escribir el options.inarchivo? ¿Puede dar un ejemplo?
Shayan
0

Estaba escribiendo un script bash con Dialog y necesitaba que esto también sucediera automáticamente. Hice esto y funcionó a las mil maravillas.

# -Wy force signaturewipe (if exists)
echo "y" | sudo lvcreate -W y -n $lvName -L "$lvSize"G /dev/"$svg" >> $nfsUtilLog
Benjamin West
fuente
-1

Puede proporcionar la entrada del usuario a su script con cat, desde un archivo de texto, canalizado a su script de bashesta manera:

cat input.txt | bash your_script.sh

Simplemente ingrese su entrada de usuario deseada en su archivo input.txt, cualquier respuesta que desee: y, n, dígitos, cadenas, etc.

WebComer
fuente
@muru Para mí, la solución que mencionaste no funcionó, así que tengo que inventar la mía.
WebComer
Improbable. Ambos describen lo mismo.
muru
La idea de @muru Alike de suministrar respuestas desde el archivo (que se puede hacer de varias maneras) no es lo mismo, y además logró una forma bastante diferente. Deberías poder verlo. Si la solución que señalas funcionara para mí, hoy no pasaré mi tiempo reinventando la rueda. Puedes usar cualquier trabajo para ti.
WebComer
@muru Creo que hay una diferencia entre los dos, algunos de los cuales se describen en las respuestas dicen aquí askubuntu.com/questions/172982/… . Para mí, por ejemplo, mi código si la salida se redirige al archivo parece más clara como un flujo natural de izquierda a derecha. Después de todo, la votación negativa de soluciones que funcionan bien como usted no estimula a las personas a compartir sus soluciones aquí. Creo que dicho dicho es suficiente para eliminar el voto negativo.
WebComer