Comment puis-je l'invite pour le Oui/Non/Annuler l'entrée dans un Linux shell script?
Je veux mettre en pause l'entrée dans un script shell, et invite l'utilisateur pour le choix. La norme de "Oui, Non, ou d'Annuler' type de question. Comment puis-je le faire dans un typique invite bash?
- Juste une remarque: la convention pour les invites sont tels que si vous présentez un
[yn]
option, celle qui est en majuscule est par défaut, c'est à dire[Yn]
par défaut est "oui", et[yN]
par défaut "aucun". Voir ux.stackexchange.com/a/40445/43532
Vous devez vous connecter pour publier un commentaire.
La plus simple et la plus largement disponible méthode pour obtenir la saisie de l'utilisateur à l'invite du shell est le
lire
de commande. La meilleure façon d'illustrer son utilisation est une démonstration simple:Une autre méthode, a souligné Steven Huwig, est Bash est
select
de commande. Voici le même exemple en utilisantselect
:Avec
select
vous n'avez pas besoin de désinfecter l'entrée de l'affiche les choix disponibles, et vous tapez un numéro correspondant à votre choix. Il a également boucles automatiquement, donc il n'y a pas besoin d'unwhile true
boucle pour recommencer si elles donnent une entrée non valide.Aussi, s'il vous plaît vérifier la excellente réponse par F. Hauri.
exit
àbreak
à garder à partir de fermeture de l'onglet lorsque j'ai sélectionné "non".break
dans leselect
si il n'y a pas de boucle?select
, non pas en raison de switch fallthough comme je le pensais.*
après en[Yy]*
? Pourquoi n'est-il pas juste[Yy]
break
est manquant, alors vous boucle pour toujours.select
n'a pas besoin de faire une pause, et j'ai modifié mon exemple en conséquence.break
dans votre exemple. Au moins la version de bash (4.2.53) je suis en utilisant les boucles de la sélectionner pour toujours jusqu'à ce quebreak
. Essayez avec cette commande:select result in asd dsa fds; do echo $result; done
ssh my-server 'path/to/myscript.sh'
. Lors de l'exécution de cette manière, le texte de l'invite pour leread -p
de commande ne s'affiche pas. Cependant, les sorties de laecho
commande. Donc, pour moi, la meilleure solution était d'utiliserecho -n "Do something? "
suivie parread yn
.command | myscript.sh
oumyscript.sh | command
. Voir cette réponse pour une solution.read -r
pour éviter readline échappe.Au moins cinq réponses pour une question générique.
Selon
et si vous voulez
1. POSIX solutions génériques
Vous pouvez utiliser le
read
commande, suivi parif ... then ... else
:(Grâce à Adam Katz commentaire: Remplacer le test ci-dessus avec celui qui est le plus portable et évite une fourche:)
POSIX, mais l'élément clé
Mais si vous ne voulez pas que l'utilisateur d'avoir à frapper Retour, vous pouvez écrire:
(Édité: Comme @JonathanLeffler à juste titre le suggère, économie stty de la configuration pourrait être mieux que de simplement les forcer à sane.)
Remarque: Cela a été testé sous sh, bash, ksh, dash et busybox!
Même, mais l'attente explicitement pour y ou n:
L'aide d'outils spécifiques
Il existe de nombreux outils qui ont été construits à l'aide de
libncurses
,libgtk
,libqt
ou d'autres graphiques bibliothèques. Par exemple, à l'aide dewhiptail
:Selon votre système, vous devrez peut-être remplacer
whiptail
avec un autre outil similaire:où
20
est la hauteur de la boîte de dialogue en nombre de lignes et de60
est la largeur de la boîte de dialogue. Ces outils ont tous près de même syntaxe.2. Bash solutions spécifiques
De base en ligne méthode
Je préfère utiliser
case
donc je pourrais même tester pouryes | ja | si | oui
si nécessaire...en ligne avec clé unique fonction
Sous bash, on peut préciser la durée prévue d'entrée pour les
read
commande:Sous bash,
read
commande accepte un délai paramètre, ce qui pourrait être utile.Quelques astuces pour outils dédiés
Plus sophistiqué des boîtes de dialogue, au-delà de la simple
yes - no
fins:Barre de progression:
Petite démo:
Plus d'exemples? Jetez un oeil à À l'aide de arubais pour choisir le périphérique USB et USB de stockage amovible, sélecteur: USBKeyChooser
5. Utiliser readline l'histoire
Exemple:
Cela va créer un fichier
.myscript.history
dans votre$HOME
répertoire, que vous pouvez utiliser readline l'historique des commandes, comme Up, Bas, Ctrl+r et les autres.stty
fournit la-g
option pour les utiliser:old_stty=$(stty -g); stty raw -echo; …; stty "$old_stty"
. Ceci restaure le paramètre exactement comme ils ont été trouvés, ce qui peut ou peut ne pas être le même questty -sane
.read answer
va interpréter les barres obliques inverses avant d'espaces et les sauts de ligne, et sinon la bande, qui est rarement prévu. Utilisationread -r answer
plutôt que par SC2162.-r
option.case
pour POSIX ainsi que bash (utilisez un caractère générique condition plutôt qu'un bash sous-chaîne:case $answer in; [Yy]* ) echo Yes ;;
), mais je préfère utiliser une instruction conditionnelle au lieu, de favoriser[ "$answer" != "${answer#[Yy]}" ]
sur votreecho "$answer" | grep -iq ^y
. Il est plus portable (certains non-GNU grep ne pas mettre en œuvre-q
correctement) et il n'a pas l'appel système.${answer#[Yy]}
utilise le paramètre d'extension pour supprimerY
ouy
depuis le début de$answer
, ce qui provoque une inégalité lorsque l'un des deux est présent. Cela fonctionne dans tout le shell POSIX (tableau de bord, ksh, bash, zsh, busybox, etc).read -n 1 -p "Is this a good question (y/n)? " answer
a fonctionné pour moi.Vous pouvez utiliser le haut- lire de commande ; Utiliser le
-p
option pour inviter l'utilisateur à une question.Depuis BASH4, vous pouvez maintenant utiliser
-i
de suggérer une réponse, alors l'utilisateur n'avez qu'à appuyer surreturn
à saisir :(Mais n'oubliez pas d'utiliser le "readline" option
-e
pour permettre l'édition de la ligne avec les touches fléchées)Si vous voulez un "oui /non" de la logique, vous pouvez faire quelque chose comme ceci:
FILEPATH
est le nom de la variable que vous avez choisi, et est définie avec la réponse à l'invite de commande. Donc, si vous exécutez ensuitevlc "$FILEPATH"
, par exemple,vlc
serait d'ouvrir ce fichier.-e
dans le deuxième exemple (simple oui/non)?-e -p
au lieu de-ep
?-e
drapeau/option, vous pouvez (en fonction de la mise en œuvre) ne pas être en mesure de taper "y", et puis changer d'avis et de le remplacer par un "n" (ou quoi que ce soit d'autre d'ailleurs) ; à la documentation d'une commande, la liste des options séparément est mieux pour la lisibilité et la clarté, entre autres raisons.Bash a sélectionnez à cette fin.
exit
à l'intérieur 🙂Ctrl-D
. Mais bien entendu, le code à l'aide, elle aura besoin d'une pause ou d'une sortie dans le corps.)exit
de sortie du script tous ensemble,break
va seulement sortir de la boucle, vous êtes-vous (si vous êtes sur unwhile
oucase
boucle)Voici quelque chose que j'ai mis en place:
Je suis un débutant, afin de prendre cela avec un grain de sel, mais il semble fonctionner.
case $yn in
àcase ${yn:-$2} in
ensuite, vous pouvez utiliser le deuxième argument est la valeur par défaut, Y ou N.Vous voulez:
Extrait de
Explications
[[ -t 0 ]] && read ...
=> Appeler la commanderead
si ATSread -n 1
=> Attendre un caractère$'\e[1;32m ... \e[0m '
=> Imprimer en vert(le vert est bien parce que lisible sur les deux blanc/fond noir)
[[ $do_xxxx =~ ^(y|Y|)$ ]]
=> bash regexTimeout => par Défaut, la réponse est Non
Le moyen le plus facile à réaliser avec le moins grand nombre de lignes est comme suit:
La
if
est juste un exemple: il est à vous comment gérer cette variable.Cette solution lit un caractère unique et appelle une fonction sur une réponse affirmative.
echo
à voir pour vous-même.Utiliser le
read
commande:et puis tous les autres trucs que vous devez
La
-e
option permet à l'utilisateur de modifier la saisie à l'aide des touches fléchées.Si vous souhaitez utiliser une suggestion d'entrée:
-i
option imprime une suggestive d'entrée.bash
(ne pas travailler danszsh
)-e
-i
ne fonctionnent pas dans sh (Bourne shell), mais la question est balisé bash spécifiquement..Désolé pour l'affichage sur un vieux post. Il y a quelques semaines, j'ai été confronté à un problème similaire, dans mon cas, j'ai besoin d'une solution qui a également travaillé au sein d'un programme d'installation en ligne-script, par exemple:
curl -Ss https://raw.github.com/_____/installer.sh | bash
À l'aide de
read yesno < /dev/tty
fonctionne très bien pour moi:Espère que cela aide quelqu'un.
tty
d'entrée comme vous ne l'aurait fait aussi bien pour vous, et a également obtenu en boucle sur la mauvaise entrée (imaginer un certain nombre de caractères dans la mémoire tampon; votre méthode de la force de l'utilisateur toujours ne pas choisir).Pour obtenir une belle ncurses-comme inputbox utilisez la commande dialogue comme ceci:
La boîte de dialogue package est installé par défaut au moins avec SUSE Linux.
Vous pouvez utiliser la valeur par défaut
REPLY
sur unread
, convertir en minuscules, et de les comparer à un ensemble de variables avec une expression.Le script prend également en charge
ja
/si
/oui
Simple pression de touche seulement
Ici est un plus, mais réutilisables et approche modulaire:
0
=oui et1
=pas dezsh
etbash
.Défaut de "non" en appuyant sur entrée
Noter que le
N
est capitalsed. Ici, la touche entrée est pressée, accepter la valeur par défaut:Aussi à noter que les
[y/N]?
a été automatiquement ajouté.La valeur par défaut "aucun" est accepté, si rien n'est fait l'écho.
Re-invite jusqu'à ce qu'une réponse valide est donné:
Défaut "oui" en appuyant sur entrée
Noter que le
Y
à l'actif du bilan:Ci-dessus, j'ai juste appuyé sur la touche entrée, de sorte que la commande est exécutée.
Pas de défaut sur entrée - exiger
y
oun
Ici,
1
ou false est retourné. Notez qu'avec cette baisse de niveau de la fonction, vous aurez besoin de fournir votre propre[y/n]?
invite.Code
Show dangerous command [y/N]? [y/n]?
etShow dangerous command [Y/n]? [y/n]?
À choix multiples version:
Exemple:
Il sera mis en
REPLY
ày
(dans le script).Inspiré par les réponses de @Mark et @Myrddin j'ai créé cette fonction universelle invite
l'utiliser comme ceci:
J'ai remarqué que personne n'a posté une réponse montrant multi-ligne echo menu pour la simple saisie de l'utilisateur donc, ici, est mon aller à elle:
Cette méthode a été publiée dans l'espoir que quelqu'un pourrait trouver utile et de gagner du temps.
Je vous suggère de utiliser la boîte de dialogue...
c'est simple et facile à utiliser, il y a aussi une version gnome appelé gdialog qui prend exactement les mêmes paramètres, mais il montre GUI style sur X.
Une façon simple de le faire est avec
xargs -p
ou gnuparallel --interactive
.J'aime le comportement de xargs un peu mieux pour cela, car il exécute chaque commande immédiatement après le message, comme d'autres interactive des commandes unix, plutôt que de collecter les yesses à exécuter à la fin. (Vous pouvez Ctrl-C, après que vous obtenez par le biais de ceux que vous voulais.)
par exemple,
xargs --interactive
est limitée à oui ou non. Tant que vous n'avez pas besoin qui peut être suffisant, mais ma question initiale a donné un exemple avec trois résultats possibles. J'aime vraiment ce que c'est streamable bien; en commun de nombreux scénarios de bénéficier de sa capacité à être joué.plus générique serait:
yn(){ read -s -n 1 -p '[y/n]'; test "$REPLY" = "y" ; } yn && echo success || echo failure
eval
s.Comme un ami de l'un d'une seule ligne de commande, j'ai utilisé les éléments suivants:
Écrit longform, il fonctionne comme ceci:
J'ai utilisé le
case
déclaration d'un couple de fois dans un tel scénario, en utilisant le cas de tresorerie est une bonne façon d'aller à ce sujet. Unwhile
boucle, qui ecapsulates lacase
bloc, qui utilise une condition booléenne peut être mis en œuvre afin de tenir encore plus de contrôle du programme, et de répondre à d'autres exigences. Après que toutes les conditions ont été remplies, unbreak
peut être utilisé, qui fera passer le contrôle de retour à la partie principale du programme. Aussi, pour répondre à d'autres conditions, bien sûr, les instructions conditionnelles peuvent être ajoutés à accompagner les structures de contrôle:case
déclaration et possiblewhile
boucle.Exemple d'utilisation d'un
case
déclaration de répondre à votre demandeOui /Non /Annuler
Fonction
D'utilisation
Confirmer avec nettoyer les entrées utilisateur
Fonction
D'utilisation
En réponse à d'autres:
Vous n'avez pas besoin de spécifier les cas dans BASH4 suffit d'utiliser la ',,' de faire un var en minuscules. Aussi, je n'aime pas mettre de code à l'intérieur du bloc de lecture, d'obtenir le résultat et de traiter avec elle à l'extérieur du bloc de lecture de l'OMI. Également inclure un 'q' pour quitter l'OMI. Enfin pourquoi le type " oui " juste utiliser -n1 et ont la appuyez sur y.
Exemple: l'utilisateur peut appuyer sur y/n et aussi q vient de quitter.