Estoy tratando de implementar un menú simple usando select
comando. La secuencia de comandos (con fines de prueba) es la siguiente:
#!/bin/bash echo "*******************" PS3="Select an option and press Enter: " options=("apache" "named" "sendmail") select opt in "${options[@]}" do case $opt in "apache") date ;; "named") echo "test" ;; "sendmail") echo "test 2" ;; *) echo "invalid option";; esac done echo "*********************"
La secuencia de comandos no reconoce ninguna entrada válida que proporcione y siempre imprime el mensaje «opción inválida». ¿Qué estoy haciendo mal en este guión?
Comentarios
- Su entrada es 1, 2 o 3, ¿verdad?
Responder
El menú que se muestra al seleccionar se verá así:
1) apache 2) named 3) sendmail Select an option and press Enter:
En este momento, ingresa » 1 «o» 2 «o» 3 «: no escribes la palabra.
Además, select
se repetirá hasta que vea un break
comando, por lo que desea esto:
case $opt in "apache") date break ;; "named") echo "test" break ;; "sendmail") echo "test 2" break ;; *) echo "invalid option";; esac
Si desea permitir que el usuario ingrese el número o la palabra, podría escribir esto:
select opt in "${options[@]}"; do case "$opt,$REPLY" in apache,*|*,apache) do_something; break ;; named,*|*,named) do_something; break ;; sendmail,*|*,sendmail) do_something; break ;; esac done
La coma no tiene significado sintáctico, está ahí para poder hacer coincidir el patrón en $ REPLY variable (que es lo que el usuario realmente escribió) o la variable $ opt
Comentarios
- El
select
comando necesita unbreak
, nocase
. - ¡Gracias! No me di cuenta de que eran opciones numéricas. ¡Duhh!
- Ja, yo también programo en C y necesitas un
break
en cada sección. Sin embargo, nunca necesitará unbreak
en un bloque case … esac en un script de shell . Puede suceder muy fácilmente confundirlos. 🙂 - @syntaxerror, ' tienes razón, no ' no necesitas
break
paracase
. Sin embargo, necesitas unbreak
para escapar del bucleselect
. - @glenn jackman Me gustaría tener esto convertido en un comentario más útil (ver a continuación). Por lo tanto, sería genial si aceptara eliminar su comentario de las 12:55. Haré lo mismo con el mío, por supuesto.
Responder
Tu $opt
variable se establecerá en la palabra de opción correspondiente al número que ingrese el usuario. Si desea ver lo que el usuario realmente escribió, consulte $REPLY
.
Comentarios
- Dado que
case
compara$opt
con " apache ", " llamado " y " sendmail ", es correcto y no se debe cambiar nada. - @manatwork, a menos que el OP quiera que el usuario escriba las palabras " Apache ", " llamado " o " sendmail " en lugar de presionar 1, 2 o 3.
- Interesante. $ REPLY contiene
1
/2
/3
, y $ opt contieneapache
/named
/sendmail
- @fred, sí,
$REPLY
es lo que haya escrito el usuario, y si era un número válido,$opt
será la palabra correspondiente a ese número.