Dans ce cas particulier, je voudrais ajouter une confirmation dans Bash pour
Êtes-vous sûr? [Y/n]
pour hg Push ssh://[email protected]//somepath/morepath
de Mercurial, qui est en fait un alias. Existe-t-il une commande standard pouvant être ajoutée à l'alias pour y parvenir?
La raison en est que hg Push
et hg out
peuvent sembler similaires et parfois lorsque je veux hgoutrepo
, je peux taper accidentellement hgpushrepo
(les deux sont des alias).
Mise à jour: si cela peut ressembler à une commande intégrée avec une autre commande, telle que: confirm && hg Push ssh://...
ça serait génial ... juste une commande qui peut demander un yes
ou no
et continuez si yes
.
Ce sont des formes plus compactes et plus polyvalentes de (Réponse de Hamish . Ils gèrent tout mélange de lettres majuscules et minuscules:
read -r -p "Are you sure? [y/N] " response
case "$response" in
[yY][eE][sS]|[yY])
do_something
;;
*)
do_something_else
;;
esac
Ou, pour Bash> = version 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
Remarque: Si $response
est une chaîne vide, une erreur se produira. Pour résoudre ce problème, ajoutez simplement des guillemets: "$response"
. - Utilisez toujours des guillemets doubles dans les variables contenant des chaînes (par exemple: préférez utiliser "$@"
à la place de $@
).
Ou, Bash 4.x:
read -r -p "Are you sure? [y/N] " response
response=${response,,} # tolower
if [[ "$response" =~ ^(yes|y)$ ]]
...
Modifier:
En réponse à votre modification, voici comment créer et utiliser une commande confirm
basée sur la première version de ma réponse (qui fonctionnerait de la même manière avec les deux autres):
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
}
Pour utiliser cette fonction:
confirm && hg Push ssh://..
ou
confirm "Would you really like to do a push?" && hg Push ssh://..
Voici à peu près un extrait que vous voulez. Permettez-moi de savoir comment transmettre les arguments.
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
Attention à yes | command name here
:)
Les confirmations sont facilement contournées avec les retours à la ligne et je trouve utile de demander continuellement une entrée valide.
Voici une fonction pour rendre cela facile. "entrée invalide" apparaît en rouge si Y | N n'est pas reçu et que l'utilisateur est invité à nouveau.
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
Vous pouvez changer l'invite par défaut en passant un argument
Pour éviter de rechercher explicitement ces variantes de 'oui', vous pouvez utiliser l'opérateur d'expression régulière bash '= ~' avec une expression régulière:
read -p "Are you sure you want to continue? <y/N> " Prompt
if [[ $Prompt =~ [yY](es)* ]]
then
(etc...)
Cela teste si l'entrée utilisateur commence par "y" ou "Y" et est suivie de zéro ou plus.
Cela peut être un bidouillage:
comme dans la question sous Unix/Bash, "xargs -p" est-il un bon moyen de demander une confirmation avant d'exécuter une commande?
nous pouvons utiliser xargs
pour faire le travail:
echo ssh://[email protected]//somepath/morepath | xargs -p hg Push
bien sûr, cela sera défini comme un alias, comme hgpushrepo
Exemple:
$ 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
$
read -r -p "Are you sure? [Y/n]" response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
your-action-here
fi
Ajoutez les éléments suivants à votre fichier/etc/bashrc. Ce script ajoute une "fonction" résidente au lieu d'un alias appelé "confirmer".
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
}
Bien, voici ma version de confirm
, modifiée de celle 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
}
Ces changements sont:
local
pour empêcher les noms de variables d'entrer en collisionread
utilise $2 $3 ...
pour contrôler son action. Vous pouvez donc utiliser -n
et -t
read
se ferme sans succès, echo
un saut de ligne pour la beautéGit on Windows
n'a que bash-3.1
et n'a ni true
ni false
, utilisez donc return
à la place. Bien entendu, cela est également compatible avec bash-4.4 (le dernier dans Git pour Windows).En retard au jeu, mais j’ai créé une autre variante des fonctions confirm
des réponses précédentes:
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 $?
}
Pour l'utiliser:
confirm your_command
Fonctionnalités:
Bogues:
echo -en
fonctionne avec bash
mais peut échouer dans votre shellecho
ou xargs
Essayer,
#!/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"
Voici une approche plus longue, mais réutilisable et modulaire:
0
= yes et 1
= nozsh
et bash
.Notez que la N
est en majuscule. Ici, appuyez sur Entrée pour accepter la valeur par défaut:
$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?
Notez également que [y/N]?
a été ajouté automatiquement. Le "non" par défaut est accepté, ainsi rien n'est renvoyé.
Ré-invite jusqu'à ce qu'une réponse valide soit donnée:
$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]? X
Show dangerous command [y/N]? y
rm *
Notez que la Y
est en majuscule:
$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *
Ci-dessus, j'ai juste appuyé sur Entrée, donc la commande a été exécutée.
y
ou n
$ get_yes_keypress "Here you cannot press enter. Do you like this"
Here you cannot press enter. Do you like this [y/n]? k
Here you cannot press enter. Do you like this [y/n]?
Here you cannot press enter. Do you like this [y/n]? n
$ echo $?
1
Ici, 1
ou false a été renvoyé. Notez pas de capitalisation dans [y/n]?
# Read a single char from /dev/tty, prompting with "$*"
# Note: pressing enter will return a null string. Perhaps a version terminated with X and then remove it in caller?
# See https://unix.stackexchange.com/a/367880/143394 for dealing with multi-byte, etc.
function get_keypress {
local REPLY IFS=
>/dev/tty printf '%s' "$*"
[[ $ZSH_VERSION ]] && read -rk1 # Use -u0 to read from STDIN
# See https://unix.stackexchange.com/q/383197/143394 regarding '\n' -> ''
[[ $BASH_VERSION ]] && </dev/tty read -rn1
printf '%s' "$REPLY"
}
# Get a y/n from the user, return yes=0, no=1 enter=$2
# Prompt using $1.
# If set, return $2 on pressing enter, useful for cancel or defualting
function get_yes_keypress {
local Prompt="${1:-Are you sure} [y/n]? "
local enter_return=$2
local REPLY
# [[ ! $Prompt ]] && Prompt="[y/n]? "
while REPLY=$(get_keypress "$Prompt"); do
[[ $REPLY ]] && printf '\n' # $REPLY blank if user presses enter
case "$REPLY" in
Y|y) return 0;;
N|n) return 1;;
'') [[ $enter_return ]] && return "$enter_return"
esac
done
}
# Credit: http://unix.stackexchange.com/a/14444/143394
# Prompt to confirm, defaulting to NO on <enter>
# Usage: confirm "Dangerous. Are you sure?" && rm *
function confirm {
local Prompt="${*:-Are you sure} [y/N]? "
get_yes_keypress "$Prompt" 1
}
# Prompt to confirm, defaulting to YES on <enter>
function confirm_yes {
local Prompt="${*:-Are you sure} [Y/n]? "
get_yes_keypress "$Prompt" 0
}
C’est peut-être un peu trop court, mais pour mon propre usage privé, cela fonctionne très bien
read -n 1 -p "Push master upstream? [Y/n] " reply;
if [ "$reply" != "" ]; then echo; fi
if [ "$reply" = "${reply#[Nn]}" ]; then
git Push upstream master
fi
Le read -n 1
ne lit qu'un caractère. Pas besoin d'appuyer sur entrer. Si ce n'est pas un "n" ou un "N", on suppose qu'il s'agit d'un "Y". Il suffit d'appuyer sur Entrée signifie aussi Y.
(comme pour la vraie question: faites-en un script bash et changez votre alias pour qu'il pointe vers ce script au lieu de ce qui était indiqué auparavant)
Voici ma solution qui utilise regex localisée. Donc, en allemand, aussi "j" pour "Ja" serait interprété comme oui.
Le premier argument est la question, si le deuxième argument est "y", alors oui serait la réponse par défaut, sinon non serait la réponse par défaut. La valeur de retour est 0 si la réponse est "oui" et 1 si la réponse est "non".
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]}
}
Voici un usage de base
# 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]? : "
Le code ci-dessous combine deux choses
shopt -s nocasematch qui tiendra compte de la casse
et si la condition accepte les deux entrées, soit vous passez oui, oui, oui, y.
shopt -s nocasematch
si [[sed-4.2.2. $ LINE = ~ (oui | y) $]]
puis sortie 0
fi
Ce n'est pas exactement un "demander oui ou non" mais juste un hack: alias le hg Push ...
non pas pour hgpushrepo
mais pour hgpushrepoconfirmedpush
et au moment où je peux tout épeler , le cerveau gauche a fait un choix logique.
Pas la même chose, mais une idée qui fonctionne quand même.
#!/bin/bash
i='y'
while [ ${i:0:1} != n ]
do
# Command(s)
read -p " Again? Y/n " i
[[ ${#i} -eq 0 ]] && i='y'
done
Sortie:
Encore? O/n N
Encore? Y/n n'importe quoi
Encore? O/n 7
Encore? Y/n &
Encore? Y/n nsijf
$
Maintenant, vérifie seulement le premier caractère de $ i read.