En Bash, ¿cómo agregar "¿Estás seguro [S/n]" a cualquier comando o alias?
En este caso particular, me gustaría agregar una confirmación en Bash para
¿Está seguro? [T/n]
para Mercurial's hg push ssh://[email protected]//somepath/morepath
, que en realidad es un alias. ¿Existe un comando estándar que se pueda agregar al alias para lograrlo?
La razón es que hg push
y hg out
puede sonar similar y, a veces, cuando quiero hgoutrepo
, puedo escribir accidentalmente hgpushrepo
(ambos son alias).
Actualización: si puede ser algo así como un comando integrado con otro comando, como: confirm && hg push ssh://...
eso sería genial... solo un comando que pueda solicitar un yes
o no
y continuar con el resto si yes
.
Estas son formas más compactas y versátiles de la respuesta de Hamish . Manejan cualquier combinación de letras mayúsculas y minúsculas:
read -r -p "Are you sure? [y/N] " response
case "$response" in
[yY][eE][sS]|[yY])
do_something
;;
*)
do_something_else
;;
esac
O, para Bash >= versión 3.2:
read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]
then
do_something
else
do_something_else
fi
Nota: Si $response
es una cadena vacía, dará un error. Para solucionarlo, simplemente agregue comillas: "$response"
. – Utilice siempre comillas dobles en variables que contengan cadenas (por ejemplo: prefiera usar "$@"
en su lugar $@
).
O, Bash 4.x:
read -r -p "Are you sure? [y/N] " response
response=${response,,} # tolower
if [[ "$response" =~ ^(yes|y)$ ]]
...
Editar:
En respuesta a su edición, así es como crearía y usaría un confirm
comando basado en la primera versión de mi respuesta (funcionaría de manera similar con las otras dos):
confirm() {
# call with a prompt string or use a default
read -r -p "${1:-Are you sure? [y/N]} " response
case "$response" in
[yY][eE][sS]|[yY])
true
;;
*)
false
;;
esac
}
Para utilizar esta función:
confirm && hg push ssh://..
o
confirm "Would you really like to do a push?" && hg push ssh://..
Aquí hay aproximadamente un fragmento que desea. Déjame descubrir cómo presentar los argumentos.
read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]
then
# http://stackoverflow.com/questions/1537673/how-do-i-forward-parameters-to-other-command-in-bash-script
else
exit 0
fi
Cuidado con yes | command name here
:)
Las confirmaciones se omiten fácilmente con retornos de carro y me resulta útil solicitar continuamente entradas válidas.
Aquí hay una función para hacer esto fácil. "Entrada no válida" aparece en rojo si no se recibe Y|N y se le pregunta al usuario nuevamente.
prompt_confirm() {
while true; do
read -r -n 1 -p "${1:-Continue?} [y/n]: " REPLY
case $REPLY in
[yY]) echo ; return 0 ;;
[nN]) echo ; return 1 ;;
*) printf " \033[31m %s \n\033[0m" "invalid input"
esac
done
}
# example usage
prompt_confirm "Overwrite File?" || exit 0
Puede cambiar el mensaje predeterminado pasando un argumento
Para evitar verificar explícitamente estas variantes de 'sí', puede usar el operador de expresión regular de bash '=~' con una expresión regular:
read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt =~ [yY](es)* ]]
then
(etc...)
Eso prueba si la entrada del usuario comienza con 'y' o 'Y' y es seguida por cero o más 'es'.
Esto puede ser un truco:
como en la pregunta En Unix/Bash, ¿es "xargs -p" una buena forma de solicitar confirmación antes de ejecutar cualquier comando?
podemos usar xargs
para hacer el trabajo:
echo ssh://[email protected]//somepath/morepath | xargs -p hg push
Por supuesto, esto se establecerá como un alias, como hgpushrepo
Ejemplo:
$ echo foo | xargs -p ls -l
ls -l foo?...y
-rw-r--r-- 1 mikelee staff 0 Nov 23 10:38 foo
$ echo foo | xargs -p ls -l
ls -l foo?...n
$