Comment utiliser les widgets ncurses dans les scripts shell sous Linux
Dans ce tutoriel, nous allons apprendre les bases de l’utilitaire de dialogue, afin d’utiliser le widget ncurses dans nos scripts shell. Nous verrons comment installer dialog dans les distributions Linux les plus utilisées, certaines des options courantes que nous pouvons utiliser pour modifier le comportement de dialog, comment utiliser certains widgets ; Parmi les autres : Inputbox, checklist, Radiolist et Yesno. Enfin, nous verrons comment utiliser les données obtenues par le traitement du widget.
Dans ce tutoriel, vous allez apprendre :
- Comment installer l’utilitaire de dialogue sur Linux
- Quelles sont les options de dialogue les plus pertinentes ?
- Comment utiliser les widgets inputbox, checklist, radiolist, passwordbox, msbox, calendar et yesno
- Comment gérer les données dérivées du traitement du widget
sudo dnf install dialogSur Debian, nous pouvons exécuter :
sudo apt-get install dialogL’utilitaire de dialogue est également contenu dans le dépôt principal d’Archlinux, nous pouvons donc l’installer via pacman :
sudo pacman -S dialogL’installation de commandes s’applique également aux dérivés des distributions mentionnées ci-dessus.
Options de boîte de dialogue courantes
Nous appelons ces options « communes » car elles peuvent être utilisées indépendamment du type de widget que nous voulons utiliser. Ici, nous n’en verrons que quelques-uns, ceux qui peuvent être d’un intérêt immédiat lorsque nous commençons à utiliser le dialogue.
Paramètres le titre d’une boîte de widget : l’option –title
En utilisant l’option --title, nous pouvons spécifier une chaîne qui sera utilisée comme titre du widget ; Il sera affiché en haut de la boîte. En voici un exemple :
dialog --title "Dialog title" --inputbox "Enter your name:" 0 0Voici ce qui est affiché comme résultat de la commande ci-dessus :
L’option --and-widget peut être utilisée pour « enchaîner » plus de widgets, de sorte qu’après avoir utilisé le premier, nous soyons immédiatement invités à utiliser le second. La chaîne est arrêtée lorsque l’une des boîtes de dialogue renvoie un état d’existence différent de zéro. Un exemple de son utilisation est :
dialog \
--inputbox "Enter your name:" 0 0 \
--and-widget --inputbox "Enter your age:" 0 0Une fois que nous lançons la commande ci-dessus, le premier widget de saisie utilisé pour nous demander notre nom s’affichera. Une fois que nous avons confirmé l’entrée en cliquant sur le bouton OK, le widget suivant s’affichera et nous serons invités à saisir notre âge.
Effacement de l’écran avec l’option –clear
Lorsque nous utilisons l’option --and-widget, le contenu créé par un widget remplace celui produit par le précédent. Si les widgets n’occupent pas exactement le même espace d’écran, les deux contenus seraient mélangés, ce qui créerait un désordre.
Pour éviter le chevauchement des contenus, nous pouvons utiliser l’option --clear ; Lorsque nous le faisons, le contenu d’un widget est effacé avant l’affichage du widget suivant : seule la couleur de fond est conservée.
Définition du bouton a comme mis en évidence par défaut : l’option –default-button
Selon le widget que nous utilisons, plus d’un bouton peut être affiché à l’écran et par défaut, l’un d’entre eux est mis en évidence par défaut, déterminant l’action par défaut à effectuer lorsque l’utilisateur appuie sur Entrée.
Nous pouvons remplacer la valeur par défaut du widget
en utilisant l’option --default-button suivie du nom du bouton, un parmi ok, yes, cancel, no, help ou extra.
Cette option peut être très utile, par exemple, lors d’une demande de confirmation avant d’exécuter une action potentiellement
dangereuse :
dialog --default-button "no" --inputbox "Enter your name:" 0 0Définition de l’élément sélectionné par défaut dans une liste avec –default-item
Lorsque nous utilisons une liste de contrôle ou un widget de menu, le premier élément de la liste des choix possibles est sélectionné par défaut. En utilisant l’option --default-item et en référençant un élément, nous pouvons l’utiliser comme valeur par défaut alternative :
dialog --default-item 2 --checklist "Select:" 0 0 5 \
1 "First element" off \
2 "Second element" off \
3 "Third element" offSpécification d’un délai après confirmation : l’option –sleep
Parfois, nous pouvons souhaiter que notre application attende un certain nombre de secondes après le traitement d’une boîte de dialogue. Pour atteindre ce comportement, nous pouvons utiliser l’option --sleep et fournir le nombre de secondes à attendre comme valeur :
dialog --sleep 3 --inputbox "Enter your name:" 0 0À la suite de la commande ci-dessus, une fois que le widget inputbox est affiché et que l’utilisateur appuie sur la touche ENTRÉE, 3 secondes sont attendues avant que la commande suivante dans le script d’appel ne soit exécutée.
Fournir un délai d’expiration du choix
Dans certains cas, nous pouvons vouloir donner à l’utilisateur un nombre maximum de secondes pour effectuer son choix. L’application de dialogue fournit l’option --timeout pour obtenir ce comportement. Le nombre de secondes de délai d’attente doit être passé en tant qu’argument de l’option. Si, après le nombre de secondes spécifié, l’utilisateur n’effectue pas son choix, l’application se fermera avec un état d’erreur :
dialog --timeout 3 --inputbox "Enter your name:" 0 0Définition d’autres libellés pour les boutons
L’utilitaire de dialogue fournit une série d’options pour remplacer l’étiquette par défaut des boutons : nous pouvons utiliser les boutons --exit-label, --extra-label, --help-label, --no-label, --ok-label, --yes-label pour changer les étiquettes des boutons « exit », « extra », « help », « no », « ok » et « yes », respectivement.
Chacune des options susmentionnées prend une chaîne de caractères comme argument, qui est utilisée comme étiquette de bouton. Voici un exemple d’utilisation de l’option :
dialog --default-button "no" \
--no-label "I don't" \
--yes-label "I do" \
--yesno "Do you really want to format the partition?" 0 0La commande ci-dessus produira le résultat suivant :
- Le texte à afficher dans le widget ;
- La largeur du widget ;
- La hauteur du widget ;
Si nous fournissons une valeur de 0 pour width ou height, la valeur de l’attribut correspondant est définie automatiquement.
Le widget inputbox
Le widget inputbox est utilisé pour inciter l’utilisateur à répondre à une question avec une saisie textuelle. Le paramètre text est utilisé pour fournir la question : si la chaîne est plus longue que la boîte de dialogue, celle-ci deviendra défilante. Pour utiliser ce widget, nous invoquons la boîte de dialogue avec l’option --inputbox :
Le widget de liste de contrôle
Nous avons déjà vu à quoi ressemble le widget de liste de contrôle dans les exemples précédents : dans ce type de widget, une série de choix est fournie à l’utilisateur qui peut en sélectionner un ou plusieurs. Pour utiliser ce widget, nous devons utiliser l’option --checklist, et, en plus des trois paramètres standard qui doivent être passés à tous les widgets, nous devons également fournir la hauteur de liste et les choix à afficher.
Le paramètre line-height permet de définir le nombre de lignes à afficher en une seule fois : si le nombre de lignes est inférieur aux choix disponibles, le menu deviendra défilant. Si nous donnons 0 comme valeur de hauteur-ligne, le nombre de lignes correspondra au nombre de choix.
Pour chaque choix, nous devons fournir un identifiant (balise), un nom et un statut qui peut être désactivé ou activé. Si le statut est activé, le choix sera coché par défaut. Une fois que nous aurons confirmé nos choix, les balises liées à l’entrée que nous avons vérifiée seront affichées sur stderr :
dialog --checklist "Select items:" 0 0 0 \
1 "Choice number one" off \
2 "Choice number two" on \
3 "Choice number three" off \
4 "Choice number four" onAvec la commande ci-dessus, nous avons lancé le menu avec 4 options, et défini les options 2 et 4 cochées par défaut. Le résultat de la commande est le suivant :
Le widget radiolist est lancé lorsque la boîte de dialogue est appelée avec l’option --radiolist. Il fonctionne de la même manière que le widget de liste de contrôle, à la différence que les choix s’excluent mutuellement, de sorte qu’un seul élément peut être sélectionné. Voici comment nous utilisons le widget :
dialog --radiolist "Select items:" 0 0 0 \
1 "Choice number one" Off \
2 "Choice number two" on \
3 "Choice number three" off \
4 "Choice number four" OffDemandez un mot de passe à l’utilisateur à l’aide du widget passwordbox
Le widget passwordbox permet d’inviter un utilisateur à saisir un mot de passe. Pour des raisons de sécurité, le texte saisi par l’utilisateur n’est pas affiché. Ce comportement peut être modifié en utilisant l’option --insecure : si nous le faisons, le widget affichera un astérisque pour chaque lettre du mot de passe saisi dans le champ correspondant.
Nous utilisons le widget en lançant la boîte de dialogue avec l’option --passwordbox :
dialog --insecure --passwordbox "Enter your password:" 0 0Le résultat de la commande ci-dessus est :
L’utilisation de ce widget est très simple : il est invoqué en appelant dialog avec l’option --msgbox et affiche un message qui est le contenu du paramètre text. Un seul bouton OK s’affiche :
dialog --msgbox "This is a very important message that should be read carefully!" 0 0Nous pouvons utiliser le widget calendrier en appelant l’utilitaire de dialogue avec l’option --calendar. Le widget nous permet de sélectionner une date en choisissant le mois, le jour et l’année qui sont affichés dans des sections distinctes du widget. Il est possible de fournir une date par défaut en la transmettant dans le cadre de la commande.
Pour démarrer le widget avec le « cinquième jour de mai de l’année 2020 » comme date par défaut, par exemple, nous exécuterions la commande suivante :
dialog --calendar "Select a date:" 0 0 27 05 2020Il produira le résultat suivant :
dialog --date-format %Y/%m/%d --calendar "Select a date" 0 0 27 05 2020Demander confirmation à l’utilisateur : le widget yesno
Nous avons déjà rencontré ce widget : il nous permet d’inviter l’utilisateur à confirmer. Lors de son utilisation, nous spécifions la question à poser via le paramètre text. En fonction du choix de l’utilisateur, un statut de sortie est renvoyé : 0 si l’utilisateur confirme en cliquant sur le bouton Oui, 1 sinon.
Pour appeler ce widget, nous devons utiliser l’option --yesno :
dialog --yesno "Do you confirm?" 0 0Voici le widget :
dialog --checklist "Select items:" 0 0 0 \
1 "Choice number one" off \
2 "Choice number two" on \
3 "Choice number three" off \
4 "Choice number four" on 2> choice.txtUne fois que l’utilisateur aura confirmé ses choix, ceux-ci seront écrits, séparés par des espaces, dans le fichier choice.txt.
Que se passe-t-il si nous voulons stocker la sélection directement dans une variable ? Pour accomplir la tâche, nous devons utiliser l’option --stdout, de sorte que la sortie du widget soit affichée sur stdin au lieu de stderr :
choices="$(dialog --stdout --checklist "Select items:" 0 0 0 \
1 "Choice number one" off \
2 "Choice number two" on \
3 "Choice number three" off \
4 "Choice number four" on)"Dans l’exemple ci-dessus, le résultat du traitement du widget, sera accessible via la variable choices. Peut-être voudrons-nous les parcourir :
for choice in ${choices}; do echo "${choice}"; done
2
4Pour gérer le processus du widget yesno, nous devons nous comporter différemment. Ledit widget, comme nous l’avons déjà vu, ne produit aucune sortie mais modifie le code de sortie de la commande utilisée pour la diffuser en fonction du choix de l’utilisateur. Si l’utilisateur confirme, et répond affirmativement à la question, le code de sortie est mis à 0, sinon à 1 (cela peut sembler étrange, mais rappelez-vous que 0 signifie OK tandis que 1 est un état de sortie qui signifie qu’une commande n’a pas réussi). Sachant cela, nous pouvons écrire quelque chose comme :
if dialog --yesno "Do you want to open an instance of gnome-terminal ?" 0 0; then
clear
gnome-terminal
fi
Conclusions
Dans ce tutoriel, nous avons vu comment nous pouvons utiliser l’application dialog pour utiliser le widget ncurses dans les scripts shell. Tout d’abord, nous avons vu certaines options courantes qui peuvent être utilisées indépendamment du type de widget, puis nous avons jeté un coup d’œil à certains widgets en particulier. Il existe de nombreux autres widgets qui peuvent être utilisés avec dialog : pour une liste complète, je vous suggère de jeter un coup d’œil au manuel d’application.