Con sintaxis POSIX sh:
#! /bin/sh -
printf 'Choose a decimal integer number between 1 and 100: '
IFS= read -r num
die() {
printf >&2 '%s\n' "$@"
exit 1
}
case $num in
("" | - | *[!0123456789-]* | ?*-*)
die "$num is not a valid decimal integer number";;
(*[123456789]??*)
die "You chose a number outside the boundaries"
esac
if [ "$num" -lt 1 ] || [ "$num" -gt 100 ]; then
die "You chose a number outside the boundaries"
fi
echo "You chose $num"
0xAA
, MMXVIII
, ¾
, 010
, 1.4e+4
, infinity
son todos números por alguna definición de número . Muchos POSIX -como shells, incluido bash
solo admiten enteros decimales en su [
integrado (y decimal, octal, hexadecimal en sus expresiones aritméticas ). Es mejor calificar exactamente qué tipo de número desea. Aquí entero decimal por ejemplo. [
es una vulnerabilidad de inyección de comando . Entonces, primero querrá verificar que el número de entrada se vea como un número. IFS= read -r line
es la sintaxis para leer una línea de entrada(aunque aquí el$IFS
-eliminación y manejo de continuación de línea de read num
probablemente estaría bien ). -o
y-a
[
están en desuso porque crean expresiones de prueba que no se pueden interpretar de forma fiable. Mientras que aquí, no sería un problema una vez que nos hayamos asegurado de que los argumentos son números enteros decimales, es mejor evitarlos. Es mejor usar varias invocaciones [
separadas por operadores de shell &&
o ||
. >&2
)y salir con un estado de salida que no sea -cero en caso de falla. [
, no se reconocería como un número (bash, dash,yash ), truncado a 19 dígitos con una advertencia (zsh ), aproximado como un número flotante (ksh93 ), o envuelto (considerado como lo mismo que 50)(mksh ). Entonces puede encontrar que [ 18446744073709551666 -gt 0 ]
devuelve falso, o que [ 18446744073709551666 -le 100 ]
devuelve verdadero. Por lo tanto, el *[123456789]??*
verifica números de más de 3 dígitos. Con bash
específicamente, puede hacerlo un poco menos incómodo con:
#! /bin/bash -
IFS= read -rp 'Choose a decimal integer number between 1 and 100: ' num
die() {
printf >&2 '%s\n' "$@"
exit 1
}
[[ $num =~ ^-?[0123456789]+$ ]] ||
die "$num is not a valid decimal integer number"
[[ $num = *[123456789]??* ]] ||
((num < 1 || num > 100)) &&
die "You chose a number outside the boundaries"
echo "You chose $num"