Esto es lo que tengo. Estoy intentando validar 3 entradas. La primera y la segunda entrada no me piden que ingrese la entrada correcta. ¿Lo que está mal?
#!/bin/bash
while :
do
echo "Please enter your tittle:"
read TITTLE
echo "Please enter your surname:"
read SURNAME
echo "Please enter your ID No."
read ID
if [ "$TITTLE" = "" ] || [ "${TITTLE//[!0-9]}" != "" ];
then
echo "Enter your valid tittle without special characters."
echo "Please try again."
exit 1
fi
if [ "$SURNAME" = "" ] || [ "${SURNAME//[!0-9]}" != "" ];
then
echo "Enter your valid surname without special characters."
echo "Please try again."
exit 1
fi
if [ "$ID" = "" ] || [ "${ID//[0-9]}" != "" ];
then
echo "Enter your valid ID No. without special characters."
echo "Please try again"
else
echo "Thank you" $TITTLE $SURNAME
break
fi
done
Respuesta1
Tu guiónsalidastan pronto como se proporciona una entrada no válida para el título o apellido, lo que inutiliza el bucle. Úselo continue
para rehacer una iteración.
Sin embargo, no desea obligar al usuario a ingresar su título y apellido nuevamente solo porque ingresó una identificación no válida, por lo que necesitará tres bucles de entrada en lugar de un bucle grande; un bucle para cada cosa que lees del usuario.
Su código es innecesariamente repetitivo y reescribirlo como lo harían tres buclestambiénser innecesariamente repetitivo. Sería más conveniente tener una función de entrada separada.
En el siguiente script lo he hecho. La función de entrada get_input
toma una "etiqueta" (alguna descripción de lo que el usuario debe ingresar) y un patrón que cada carácter de la entrada debe coincidir. La get_input
función genera la cadena válida en la salida estándar, razón por la cual la llamamos dentro de una sustitución de comando en la parte principal del script.
También moví la validación de cadena a su propia función. Esto es para hacer la get_input
función más limpia y separar la lógica de validación de la lógica de entrada.
La validación utiliza el mismo enfoque que usted, es decir, elimina todos los caracteres de la cadena que son válidos y luego prueba si queda algún carácter, en cuyo caso la cadena no pasa la validación.
#!/bin/bash
# Succeeds if the first argument is non-empty and only
# consists of characters matching the pattern in the
# second argument.
is_valid () {
local string pattern
string=$1
pattern=$2
[ -n "$string" ] && [ -z "${string//$pattern}" ]
}
# Asks user for input until the given string is valid.
# The first argument is a text string describing what
# the user should enter, and the second argument is a
# pattern that all characters in the inputted data much
# match to be valid.
get_input () {
local label pattern
local string
label=$1
pattern=$2
while true; do
read -r -p "Please enter $label: " string
if is_valid "$string" "$pattern"; then
break
fi
# Complain on the standard error stream.
printf 'Invalid input, try again\n' >&2
done
printf '%s\n' "$string"
}
# Get data from user.
title=$( get_input 'your title' '[[:alpha:] ]' ) # title: only letters and spaces
surname=$( get_input 'your surname' '[[:alpha:] ]' ) # surname: same as title
id=$( get_input 'your ID no.' '[[:digit:]]' ) # ID: only digits
# Print what we got.
printf 'Title = "%s"\n' "$title"
printf 'Surname = "%s"\n' "$surname"
printf 'ID = "%s"\n' "$id"
Para permitir también, por ejemplo, puntos en el título o apellido, cambie el patrón de [[:alpha:] ]
a [[:alpha:]. ]
. O bien, puede ser incluso menos restrictivo y [![:digit:]]
permitir cualquier carácter que no sea un dígito (incluidos los signos de puntuación, etc.)
Para guardar el resultado en un archivo con el mismo nombre que el usuario que ejecuta el script, redirija el resultado del script:
$ ./script.sh >"$USER.txt"
Esto ejecutaría el script y redirigiría la salida a un archivo llamado $USER.txt
, donde $USER
está el nombre de usuario del usuario actual (esta variable y $LOGNAME
generalmente ya están configuradas por el shell y/o el sistema).
También puedes hacer esto dentro del propio script cambiando las últimas tres printf
líneas a
# Print what we got.
{
printf 'Title = "%s"\n' "$title"
printf 'Surname = "%s"\n' "$surname"
printf 'ID = "%s"\n' "$id"
} >"$USER.txt"
O, si desea utilizar el "apellido" leído por el usuario en el script:
# Print what we got.
{
printf 'Title = "%s"\n' "$title"
printf 'Surname = "%s"\n' "$surname"
printf 'ID = "%s"\n' "$id"
} >"$surname.txt"
Atambiénimprima en la terminal, use tee
:
# Print what we got.
{
printf 'Title = "%s"\n' "$title"
printf 'Surname = "%s"\n' "$surname"
printf 'ID = "%s"\n' "$id"
} | tee "$surname.txt"
Tenga en cuenta que el uso de la entrada proporcionada por el usuario potencialmente permite al usuario del script sobrescribir archivos arbitrarios en el directorio actual (siempre que los permisos lo permitan).