Este es uno de los capítulos del tutorial Scripts en Bash. Encontrarás los enlaces a todos los de capítulos, al final de este artículo.
Sinceramente, no suelo hacer scripts en los que, sea necesaria la intervención de un humano, en los que sea necesario preguntar al usuario en Bash. Por supuesto que para, o bien lanzarlo, o bien, programarlo en un cron, es necesaria la intervención humana. Igualmente es posible, pero no imprescindible, que sea necesario pasar argumentos para el correcto funcionamiento del script. Sin embargo, todas estas operaciones se realizan antes de iniciar el script. Por el contrario, es posible, solicitar al usuario que introduzca algún parámetro, pero en tiempo de ejecución. Es decir, se trata de que una vez se ha iniciado el script, tu script te pregunte por un parámetro o variable. Se trata de preguntar al usuario en Bash.
Pero, ¿cuando necesitas que tu script te pregunte?¿cuando necesitas que el script detenga su ejecución hasta que le respondas? ¿cuando necesitas preguntar al usuario en Bash?En mi caso particular, lo utilizaría, para realizar pruebas, para facilitar la entrada de un determinado parámetro que quieres probar de forma puntual. Pero, también lo puedes utilizar para introducir una contraseña que no quieres que se guarde en un archivo, aunque se encuentre en el anillo de claves de GNOME, o por ejemplo, también para realizar algún juego, como podría ser el ahorcado…
En fin, lo utilices para lo que lo quieras utilizar, se trata de una posibilidad que tienes a tu disposición, y que es interesante conocer.
Preguntar al usuario en Bash
La solución para preguntar al usuario en Bash es utilizar el comando integrado de Bash read. Con read
puedes leer desde tu script desde la entrada estándar. El uso de este comando es tremendamente sencillo. Con un ejemplo,
#!/bin/bash
echo Introduce tu nombre
read nombre
echo Tu nombre es $nombre
Hasta que no introduzcas tu nombre (o lo que quieras) el script estará detenido a la espera de que introduzcas una nueva línea o retorno de carro. Es posible definir otro delimitador que no sea un retorno de carro, pero esto lo podrás ver mas adelante.
La pregunta en el mismo read
En el apartado anterior, he utilizado un echo
para mostrar la pregunta. Sin embargo, esto no es necesario, porque read
ya tiene previsto una opción para esto, se trata de -p <mensaje>
. Así por ejemplo,
#!/bin/bash
read -p "Dime tu nombre: " nombre
if [ "$nombre" != "" ]
then
echo "Hola $nombre"
else
echo "Pues si no me quires decir tu nombre peor para ti"
fi
Las respuestas del usuario a un array
¿Y si le preguntamos por varios parámetros y queremos guardarlos en un array? En este caso tienes que utilizar la opción -a
. Por ejemplo,
#!/bin/bash
echo Dime tres nombres
read -a nombres
for i in ${nombres[@]}
do
echo $i
done
Con esta sencilla operación todo lo que introduzcamos irá al array. En este sentido, ten en cuenta que, si no utilizas comillas, simples o dobles, cada elemento separado por un espacio es un elemento del array.
Un timeout para los impacientes
Otra interesante opción que tienes a tu alcance es la de definir un tiempo máximo para contestar. De esta forma, transcurrido el tiempo definido, si el usuario no ha respondido se continua con el proceso.
Esto te puede resultar muy interesante para dar la posibilidad de hacer el script automático, o incluso, si así lo consideras para hacer el juego del ahorcado como te he comentado anteriormente.
Para utilizar el timeout, tienes que emplear la opción -t
seguido del tiempo. Un ejemplo, donde preguntamos el nombre del usuario, y si no responde en menos ded dos segundos, te lo dice,
#!/bin/bash
read -t 2 -p "Dime tu nombre: " nombre
if [ -z $nombre ]
then
echo
echo "No me has dicho tu nombre en menos de dos segundos"
else
echo $nombre
fi
Limitar el número de caracteres
También es interesante poder limitar el número de caracteres que se pueden introducir. Sería una solución tipo Twitter. Tu puedes definir el número de caracteres que permites introducir. Además tienes dos variantes como puedes leer a continuación,
-n
solo permite un número de caracteres como máximo siempre y cuando no hayas utilizado el delimitador, que por defecto, como he comentado anteriormente es el retorno de carro.-N
en este caso se permite un número de caracteres, pero se ignora el delimitador. De esta forma, hasta que no se alcanza el número de caracteres prefijado o se produce un timeout, en el caso de que lo hayas utilizado, no se considera la respuesta.
Por ejemplo,
#!/bin/bash
read -n 7 -p "Fruta de siete letras: " fruta
if [ "$fruta" == "plátano" ]
then
echo
echo Correcto
else
echo
echo "Error, la respuesta correcta era plátano"
fi
De esta manera, cuando hayas introducido la séptima letra no hará falta que introduzcas el retorno de carro, o el delimitador, en el caso de que lo hayas modificado.
Cambiando el delimitador
Como he comentado en diferentes apartados a lo largo de este capítulo del tutorial, es posible seleccionar otro delimitador que no sea el retorno de carro. De esta manera, cuando el usuario de tu script introduzca ese delimitador se leerá la entrada.
Modificando un poco el ejemplo anterior, y de forma un poco absurda. Lo que conseguiríamos es que al introducir la letra o
directamente se continuara con el script. El problema, es si el usuario de tu script no acierta con ese delimitador…
#!/bin/bash
read -d o -p "Fruta de siete letras: " fruta
if [ "$fruta" == "plátan" ]
then
echo "Correcto"
else
echo "Error, la respuesta correcta era plátano"
fi
Fíjate en el detalle, que al realizar la comparación solo he tenido en cuenta plátan
y he omitido la o
, porque en este caso al hacer de delimitador no forma parte de la respuesta. Esto, es un pequeño detalle, pero lo tienes que tener en cuenta.
Y se hizo el silencio o como trabajar con contraseñas
¿Como preguntar al usuario por una contraseña? Lo típico es que al escribir la contraseña no se muestre ningún carácter, para de esta manera, evitar que miradas indiscretas se queden con la misma.
Para este caso read
también tiene prevista una opción que seguro que te va a solucionar este problema. Se trata de -s
(s
de silencio). Simplemente no va a mostrar los caracteres conforme los introduzcas.
Por ejemplo,
#!/bin/bash
read -sp "Introduce la contraseña: " password
echo $password
Ciertamente no tiene sentido que hagas posteriormente un echo
de la contraseña que acaba de introducir el usuario, pero es para mostrar de forma gráfica el ejemplo.
Conclusión
Como has podido leer, read
, te ofrece diferentes opciones para preguntar al usuario por un determinado parámetro, y detener de esta forma el script. Aunque, siempre es posible definir un tiempo máximo, en el que si el usuario no responde tu continuas, pero no creo que esto sea lo mas correcto.
Más información,
Hola! Excelente artículo. Me ha servido de mucho, gracias! Me gustaría saber como puedo limitar solo 2 caracteres para responder Y o n según sea el caso. Imagino que con -d podría hacerlo.