En Bash, cómo agregar "¿Estás seguro[Y/n]" de algún comando o alias?
confirmation (15)
Agregue lo siguiente a su archivo / etc / bashrc. Este script agrega una "función" residente en lugar de un alias llamado "confirmar".
function confirm( )
{
#alert the user what they are about to do.
echo "About to $@....";
#confirm with the user
read -r -p "Are you sure? [Y/n]" response
case "$response" in
[yY][eE][sS]|[yY])
#if yes, then execute the passed parameters
"$@"
;;
*)
#Otherwise exit...
echo "ciao..."
exit
;;
esac
}
En este caso particular, me gustaría agregar una confirmación en Bash para
Are you sure? [Y/n]
para hg push ssh://[email protected]//somepath/morepath
de Mercurial, hg push ssh://[email protected]//somepath/morepath
, que en realidad es un alias. ¿Hay un comando estándar que se pueda agregar al alias para lograrlo?
La razón es que hg push
y hg out
pueden sonar similares y, a veces, cuando quiero hgoutrepo
, accidentalmente hgpushrepo
escribir hgpushrepo
(ambos son alias).
Actualización: si puede ser algo así como un comando incorporado con otro comando, como: confirm && hg push ssh://...
eso sería genial ... solo un comando que puede pedir un yes
o no
y continúa con el resto si es así.
Aquí está mi solución que usa regex localizado. Entonces en alemán también "j" para "Ja" se interpretaría como sí.
El primer argumento es la pregunta, si el segundo argumento es "y", entonces sí sería la respuesta predeterminada, de lo contrario, no sería la respuesta predeterminada. El valor de retorno es 0 si la respuesta fue "sí" y 1 si la respuesta fue "no".
function shure(){
if [ $# -gt 1 ] && [[ "$2" =~ ^[yY]*$ ]] ; then
arg="[Y/n]"
reg=$(locale noexpr)
default=(0 1)
else
arg="[y/N]"
reg=$(locale yesexpr)
default=(1 0)
fi
read -p "$1 ${arg}? : " answer
[[ "$answer" =~ $reg ]] && return ${default[1]} || return ${default[0]}
}
Aquí hay un uso básico
# basic example default is no
shure "question message" && echo "answer yes" || echo "answer no"
# print "question message [y/N]? : "
# basic example default set to yes
shure "question message" y && echo "answer yes" || echo "answer no"
# print "question message [Y/n]? : "
Aquí hay aproximadamente un fragmento que desea. Déjame saber cómo reenviar 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://.com/questions/1537673/how-do-i-forward-parameters-to-other-command-in-bash-script
else
exit 0
fi
Cuidado con yes | command name here
yes | command name here
:)
Bueno, aquí está mi versión de confirm
, modificada de la de James:
function confirm() {
local response msg="${1:-Are you sure} (y/[n])? "; shift
read -r $* -p "$msg" response || echo
case "$response" in
[yY][eE][sS]|[yY]) return 0 ;;
*) return 1 ;;
esac
}
Estos cambios son:
- use
local
para evitar que los nombres de las variables colisionen -
read
uso de$2 $3 ...
para controlar su acción, por lo que puedes usar-n
y-t
- si
read
sale sin éxito,echo
un avance de línea para belleza - mi
Git on Windows
solo tienebash-3.1
y no tienetrue
ofalse
, así que usereturn
enreturn
lugar. Por supuesto, esto también es compatible con bash-4.4 (el actual en Git para Windows). - use el estilo de IPython "(y / [n])" para indicar claramente que "n" es el valor predeterminado.
El siguiente código combina dos cosas
shopt -s nocasematch que se ocupará de las mayúsculas y minúsculas
y si la condición que aceptará ambas entradas ya sea que pase sí, sí, SÍ, y.
shopt -s nocasematch
si [[sed-4.2.2. $ LINE = ~ (yes | y) $]]
luego salga 0
fi
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 bien, 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 las variables que contienen cadenas (por ej .: prefiere usar "$@"
lugar de $@
).
O bien, 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, he aquí cómo crearía y usaría un comando de confirm
basado en la primera versión de mi respuesta (funcionaría de manera similar con los otros 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 usar esta función:
confirm && hg push ssh://..
o
confirm "Would you really like to do a push?" && hg push ssh://..
Esto no es exactamente un "pidiendo sí o no", sino solo un truco: alias el hg push ...
del hg push ...
no para hgpushrepo
sino para hgpushrepoconfirmedpush
y cuando puedo deletrear todo, el cerebro izquierdo ha hecho una lógica elección.
Esto puede ser un poco corto, pero para mi uso privado, funciona muy bien
read -n 1 -p "Push master upstream? [Y/n] " reply;
if [ "$reply" != "" ]; then echo; fi
if [ "$reply" != "n" ]; then
git push upstream master
fi
La read -n 1
solo lee un carácter. Si no es una ''n'' minúscula, se supone que es una ''Y''.
(en cuanto a la pregunta real: hacer que un script bash y cambiar su alias para apuntar a ese script en lugar de lo que estaba apuntando antes)
Esto puede ser un truco:
como en cuestión En Unix / Bash, ¿es "xargs -p" una buena forma de pedir 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
$
Las confirmaciones se pueden omitir fácilmente con retornos de carro, y me resulta útil pedir continuamente una entrada válida.
Aquí hay una función para hacer esto fácil. "entrada inválida" aparece en rojo si Y | N no se recibe, y se le solicita 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 la solicitud predeterminada pasando un argumento
No es lo mismo, pero la idea de que funciona de todos modos.
#!/bin/bash
i=''y''
while [ ${i:0:1} != n ]
do
# Command(s)
read -p " Again? Y/n " i
[[ ${#i} -eq 0 ]] && i=''y''
done
Salida:
¿De nuevo? S / n N
¿De nuevo? S / n nada
¿De nuevo? S / n 7
¿De nuevo? S / n &
¿De nuevo? Y / n nsijf
ps
Ahora solo verifica el 1er personaje de $ que leo.
Para evitar la verificación explícita de estas variantes de ''sí'', podría usar el operador de expresión regular 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 seguido por cero o más ''es''.
Tarde en el juego, pero creé otra variante de las funciones de confirm
de las respuestas anteriores:
confirm ()
{
read -r -p "$(echo $@) ? [y/N] " YESNO
if [ "$YESNO" != "y" ]; then
echo >&2 "Aborting"
exit 1
fi
CMD="$1"
shift
while [ -n "$1" ]; do
echo -en "$1/0"
shift
done | xargs -0 "$CMD" || exit $?
}
Para usarlo:
confirm your_command
caracteristicas:
- imprime tu comando como parte del aviso
- pasa argumentos usando el delimitador NULL
- preserva el estado de salida de su comando
Loco:
-
echo -en
funciona conbash
pero puede fallar en tu caparazón - podría fallar si los argumentos interfieren con
echo
oxargs
- un trillón de otros errores porque las secuencias de comandos shell es difícil
Tratar,
#!/bin/bash
pause ()
{
REPLY=Y
while [ "$REPLY" == "Y" ] || [ "$REPLY" != "y" ]
do
echo -e "/t/tPress ''y'' to continue/t/t/tPress ''n'' to quit"
read -n1 -s
case "$REPLY" in
"n") exit ;;
"N") echo "case sensitive!!" ;;
"y") clear ;;
"Y") echo "case sensitive!!" ;;
* ) echo "$REPLY is Invalid Option" ;;
esac
done
}
pause
echo "Hi"
read -r -p "Are you sure? [Y/n]" response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
your-action-here
fi