Programmation en Shell Bash Linux

De Wiki Amis SH
Aller à la navigation Aller à la recherche



Le wiki : Accueil - Administrateur - Bureautique - Développeur - Intégrateur - Marketing - Multimédia - Objets numériques - Jeux - We make Hack


Programmation en Shell Bash Linux

Programmation en Shell Bash Linux est un pense bête pour créer des scripts interactifs.

Code retour

Par convention, un code de retour égal à 0 signifie que la commande s'est exécutée correctement.
Un code différent de 0 signifie soit une erreur d'exécution, soit une erreur syntaxique.
sudo apt-get install PROGRAMME_INCONNU
Évidemment aucun logiciel ne va s'installer.
echo $?
Le code erreur 100 est affiché sur la console.
Le code erreur n'est pas 0, donc, la commande qui a été lancée n'a pas aboutie.
ls
if [ "$?" = "0" ] ; then
echo "OK"
else
echo "NOK"
fi
Mettre en place le retour erreur après chaque action.
Exemple pour l'utilisation du paquet apt clean :
apt clean
if [ "$?" = "0" ] ; then
echo "Les paquets présents dans /var/cache/apt/archives ont été supprimés."
else
echo "Les paquets présents dans /var/cache/apt/archives n'ont pas été supprimés."
fi
Source complémnetaire : okki666.free.fr/docmaster/articles/linux131.html
Autre possibilité, récupérer ce que apt-get envoie dans stderr pour avoir les messages d'erreur.

Variables et portée des variables

Variables spéciales initialisées automatiquement au début du script

$0 	Le nom de la commande (i.e. : du script)
$1, $2, ... 	Le premier, deuxième, ... argument passés au script.
$* 	La liste de tous les arguments passés au script.
$# 	Le nombre d'arguments passés au script.
$? 	Le code de retour de la dernière commande lancée.
$! 	Le numéro de process de la dernière commande lancée en tâche de fond.
$$ 	Le numéro de process du shell lui-même.

Variables d'environnement

$HOME   chemin du répertoire personnel de l'utilisateur
$OLDPWD   chemin du répertoire précédent
$PATH   liste des chemins de recherche des commandes exécutables
$PPID   PID du processus père du shell
$PS1   invite principale du shell
$PS2   invite secondaire du shell
$PS3   invite de la structure shell "select"
$PS4   invite de l'option shell de débogage "xtrace"
$PWD   chemin du répertoire courant
$RANDOM   nombre entier aléatoire compris entre 0 et 32767
$REPLY   variable par défaut de la commande "read" et de la structure shell "select"
$SECONDS   nombre de secondes écoulées depuis le lancement du shell

Exporter une variable

Une variable peut être supprimée avec la commande unset, et peut être verrouillée avec la commande readonly.
moi=Zer00CooL
echo $moi
Le résultat affiche Zer00CooL.
On verrouille la variable moi et on tente de la supprimer.
readonly moi
unset moi
On obtient un message d'erreur : bash: unset: moi: cannot unset: readonly variable
Portabilité de la variable moi dans les autres scripts appelés par le script d'origine, avec la commande export.
export moi
Le script utilisant la variable exportée moi, ne peut pas la modifier.
Les données peuvent "descendre" mais pas "remonter".

Utiliser une variable globale à l'aide d'une fonction

#!/bin/bash
fonction_portabilite_variable ()
{
global_var=Bonjour 
}

echo "global_var = $global_var"
# global_var =
# La fonction "fonction_portabilite_variable" n'a pas été appelée. $global_var n'est pas visible.

fonction_portabilite_variable
echo "global_var = $global_var"
# global_var affiche Bonjour
# La variable "global_var" a été définie par appel de fonction.
Noter qu'une fonction peut être exportée avec la commande export -f fonction_portabilite_variable

Afficher le résultat d'une commande avec une fonction et echo

# Afficher la position actuelle dans le serveur depuis le terminal :
my_function_using_echo() {
   pwd;
}
echo "Notre position sur le serveur : $(my_function_using_echo)";
# Obtenir le CHMOD du fichier wp-config.php
function_chmod_wpconfig() {
    stat -c '%a' wp-config.php;
}
echo "Son CHMOD actuel est $(function_chmod_wpconfig).";

Remonter une variable enfant vers parent

Exemple 1

#!/bin/bash
# Utiliser un fichier intermédiaire.
mknod fifo p
(
      echo 'Bonjour' > fifo &
)
VARIABLE=`cat fifo`
echo $VARIABLE
rm fifo

Exemple 2

# Fichier parent.
#!/usr/bin/ksh
echo "In parent"
second   
. env_file
echo "The value of MSG is : $MSG"

# Fichier enfant.
#!/usr/bin/ksh
echo "In child"
export MSG="ENVIRON"
printenv | sed 's/^/export /;s/=/=\"/;s/$/\"/' > env_file

En exécutant le fichier parent, on obtient bien les valeurs définies depuis le fichier enfant.
In parent
In child
The value of MSG is : ENVIRON
What did we do:
1. In the script 'second', after setting the environment variable, the list of all environment variables(printenv) is copied to a temporary file env_file.
2. The sed command is used to add the word 'export' at the beginning of every environment variable, and to wrap the variable value with double-quotes. This will enable us to simply run the file in the parent shell to export the variables.
3. In the parent 'first', the script 'second' is called. After the call to the 'second', all the environment variables are being sourced using the dot(.) command, and hence all the variables are now available in the parent as well.
4. On printing the variable VAR, got the value being set in the child and hence accessed the child shell environment variable in the parent.

Exemple 3

There is no  way to pass new variable value from the child shell to the parent shell. You may use files to communicate.
### A tester...
# Test 1
# Script 1
var1=1 ; export var1
echo $var1
./script2
echo $var1
echo $var2
# Script 2
echo $var1
var1=2
echo $var1
var2=3 ; export var2
# Test 2
# Script 2
echo 1 > /tmp/f1
# Script 1
var=`cat /tmp/f1`
echo $var
echo $var2

Différents types de variables

Source : http://www.epons.org/shell-bash-variables.php

Échapper un caractère dans une chaine

# Échapper la simple quote '.
# Utiliser PHP permet par exemple d'échapper avec la commande suivante :
echappement=$(echo "John O'hara"  | php -R 'echo addslashes($argn);')
echo $echappement
# On préfèrera utiliser sed, par défaut, quand c'est possible
chaine="Chaine avec l'un des problèmes de caractères pouvant être rencontré, la simple quote."
echappement=$(echo "$chaine" | sed s/"'"/"\\\'"/g)
echo $echappement

Créer un fichier de logs avec date heure minutes secondes

# Variables jour et heure.
jour=$(date %d-%m-+%Y)
heure=$(date +%H:%M:%S)

cd /home/user/dossier
echo "$jour - $heure : Mise en route du script." >> logs.txt

Connaître la date de création d'un fichier au format Timestamp

Date_Modif_Fichier=`perl -e '($atime,$mtime,$ctime)=(stat($ARGV[0]))[8..10];print "$mtime\n";' 00-menu.sh `
Date_Du_Jour=`date -u '+%s'`

echo " Date du jour : `date "+%d %B %Y %H:%M:%S"` "
echo
echo " Le timestamp (unix) désigne le nombre de secondes écoulées depuis le 1er janvier 1970 à minuit UTC précise. "
echo
echo " Date du jour au format Timestamp : $Date_Du_Jour "
echo " Date de modification du fichier au format Timestamp : $Date_Modif_Fichier "

echo
calcul=`expr $Date_Du_Jour - $Date_Modif_Fichier`
echo " Date du jour - Date de modification du fichier : $calcul secondes. "

calcul=`expr $calcul / 60`
echo " $calcul minute(s) "

if [ $calcul -gt 1 ]; then
echo " Le fichier n'est pas à jour avec $calcul minutes de durée de vie. "
else
echo " Le fichier est à jour avec $calcul minute de durée de vie. "
fi

Date

Supprimer des fichiers en fonction de leur date d'ancienneté : http://webdevpro.net/script-de-bash-pour-supprimer-des-fichiers-et-dossiers-en-fonction-dune-periode/
Supprimer des fichiers en fonction de leur date d'ancienneté : http://www.informatix.fr/tutoriels/unix-linux-bsd/comment-supprimer-les-fichiers-plus-vieux-qu-une-date-donnee-en-bash-117

TimeStamp

# TimeStamp vers Date
# perl -e "print scalar(localtime(1173279767))"
# Date vers TimeStamp
perl -e "use POSIX ; print (mktime(10,45,11,31,4,107));"
Pour utiliser l'heure locale française :
date -d 2005-10-20 +"%s
Noter que cette commande ne fonctionne PAS sur unix (Aix), il faut alors charger shellutils : directory.fsf.org/GNU/shellutils.html

Vider l'écran du terminal

clear
reset

Juste pour le fun

Afficher une image ascii dans le terminal

cat ascii-seo.sh

Créer son horloge parlante en Bash sous Linux

#! /bin/bash
######################
## Horloge parlante ##
######################

## Donner les droits d'exécution :
# chmod +x horloge.sh

## Installer espeak :
# sudo apt install espeak

## Ajouter le paquet de langue améliorée pour la commande " mb/mb-fr1 " :
## Télécharger la voix Mbrola FR1 :
# cd /usr/share
# sudo mkdir mbrola
# cd mbrola
# sudo mkdir fr1
# cd fr1
# sudo wget https://raw.githubusercontent.com/numediart/MBROLA-voices/master/data/fr1/fr1

## Lancer l'horloge parlante pour tester le script :
# sh horloge.sh
## Changer d'heure en changeant de fuseau horaire :
# cp /usr/share/zoneinfo/Europe/Athens /etc/localtime
# cp /usr/share/zoneinfo/Europe/Lisbon /etc/localtime
# J'ai rencontré des problèmes lors de la copie vers le localtime pour la valeur Paris. Utiliser Brussels si besoin pour avoir l'heure de Paris.
# cp /usr/share/zoneinfo/Europe/Paris /etc/localtime
# cp /usr/share/zoneinfo/Europe/Brussels /etc/localtime

## Démarrer le script avec une tâche cron 1 minute avant le changement d'heure.
# crontab -e
# 59 * * * * sh /home/utilisateur/chemin/chemin/horloge.sh

## Aucune action n'est requise ci-dessous !
## L'horloge parlante est configurée !

hmem=$(date +%-H)
hnow=$(date +%-H)

while :
do
    # Vérifier l'heure actuelle à l'intérieur de la boucle.
    hnow=$(date +%-H)
    
    # Afficher l'heure actuelle et l'heure mémorisée :
    # echo "Heure actuelle : $hnow - Heure mémorisée : $hmem "

    if [ $hnow != $hmem ]
    then

        # echo "Heure changée"
        # Afficher un son différent, 11.mp3 12.mp3 ... pour chaque possibilité :
        # DISPLAY=:0 /usr/bin/mplayer /home/utilisateur/chemin/chemin/$hnow.mp3

        # Synthèse vocale avec espeak :
        # date "+Il est %H heure %M" | espeak -v fr

        # Affecter l'heure actuelle à une variable heure qui sera lue par espeak :
        heure=$hnow
        # Mettre en place une exception pour 21h qui se dit "vingt et une" :
        if [ $heure = 21 ]
        then
            heure="vingt et une"
        fi
        # Mettre en place une exception pour 0h qui se dit "minuit" :
        if [ $heure = 0 ]
        then
            heure="minuit"
        fi
        # Mettre en place une exception pour 1h qui se dit "une" et pas "un" :
        if [ $heure = 1 ]
        then
            heure="une heure"          
        else
            heure="$heure heures"
        fi

        # Après avoir installé le fichier mbrola fr1 cette alerte de voix devient très sympa :
        espeak "L'heure change ! ... Il est $heure" -s 100 -v mb/mb-fr1
        # On affecte la nouvelle valeur à l'heure mémorisée pour que la condition ne soit plus réalisée :
        hmem=$hnow

        # Tuer le script qui tournerait sinon pendant une heure. Le script sera relancé avec une tâche cron.
        exit 0
    else
        #echo "L'heure n'a pas changée"
        # espeak "L'heure n'a pas changée !" -s 100 -v mb/mb-fr1
        sleep 5
    fi

done

# Note concernant les processus fantômes durant les tests :

# Identifier les processus qui tournent :
# ps aux
# Tuer un processus avec son pid :
# sudo kill -9 26550

# Lister tous les processus lancés pour le script horloge.sh
# ps -ef | grep horloge.sh
# Pour n'avoir que le pid :
# pgrep horloge.sh

# Partagé sur : https://wiki.visionduweb.fr/index.php?title=Programmation_en_Shell_Bash_Linux#Cr.C3.A9er_son_horloge_parlante_en_Bash_sous_Linux
# Partagé également depuis le fichier pastebin : https://pastebin.com/n5jaF8gs
# D'après la vidéo suivante : https://youtu.be/UbqU7rxu-eU

Utiliser la commande awk

awk est une commande très puissante, un langage de programmation a elle tout seule qui permet une recherche de chaînes et l'exécution d'actions sur les lignes sélectionnées.
Cette commande est utile pour récupérer de l'information, générer des rapports, transformer des données entre autres.
Une grande partie de la syntaxe a été empruntée au langage c, d'ailleurs awk sont les abréviations de ces 3 créateurs dont k pour Kernighan, un des inventeurs du c. 
Exemple de la commande :
myvar="toto" cat $fic | awk '{ sub(/'$myvar'/,"commentaire"); print}'
Application :
[jp@MDK trash]$ cat fich.txt Je m'appelle Toto et moi Tutu et mon frère Titi. [jp@MDK trash]$ var="Toto" [jp@MDK trash]$ cat fich.txt | awk '{ sub(/'$var'/,"Tata");print}' Je m'appelle Tata et moi Tutu et mon frère Titi. [jp@MDK trash]$
Lire les logs plus facilement avec awk pour ne pas afficher les doublons.
Par exemple, dans le cas du fichier de logs Joomla : administrator/logs/error.php
cat error.php | awk '!x[$3]++'
Une liste avec des IP unique sera affichée, permettant un traitement rapide des adresses à bannir.
 Source : http://www.shellunix.com/awk.html
 Source : http://www.funix.org/fr/unix/awk.htm
 Source : http://www.theunixschool.com/p/awk-sed.html
 Source : https://linuxconfig.org/learning-linux-commands-awk

Utiliser la commande sed

Remplacer une ligne entière

Remplacer une ligne entière par "Tata" uniquement si cette ligne contient "appelle" ?
$ cat plop
Je m'appelle Toto
et moi Tutu
et mon frère Titi.
$ sed '/appelle/cTata' plop
Tata
et moi Tutu
et mon frère Titi.

Rendre les fichiers de configuration plus lisibles

# Les fichiers de configuration contiennent souvent de nombreux commentaires.
# Afficher le contenu d'un fichier de configuration sans les lignes de commentaires pour rendre le fichier plus lisible sur le terminal :
sudo more fichier.conf | sed '/ *#/d; /^ *$/d'
# Rediriger la sortie vers un nouveau fichier sans commentaires :
sudo more fichier.conf | sed '/ *#/d; /^ *$/d' > fichier-sans-commentaire.conf
# Faciliter la lecture des fichiers de configuration en production en supprimant tous les commentaires présents par défaut.
# Attention, en relisant le fichier en production, les exemples de commandes qui n'ont pas été activées ne seront plus présents.
# Il sera donc indispensable d'étudier le fichier par défaut pour connaître les options qui devront être activées dans la configuration en production.
# On peut créer une copie du fichier de configuration, sans les commentaires!,
# On peut également créer une copie du fichier de configuration avec les commentaires pour recréer le fichier de configuration sans commentaires.
# Tout dépend de ce que l'on souhaite faire, et, de notre niveau de compréhension de la configuration du service à paramétrer.
# Rien n'empêche de commenter soit même le nouveau fichier en production, dans sa langue, avec ses propres commentaires.
# Sauvegarder une copie de la configuration existante par défaut :
sudo cp fichier.conf fichier.conf.defaut
# Enlever les commentaires :
sudo su
sudo more fichier.conf.defaut | sed '/ *#/d; /^ *$/d' > fichier.conf

Ajouter un espace après tous les points

Ajouter un espace après chaque point ou caractères de ponctuation avec la commande sed 's/\./\. /g' input.txt > output.txt

Supprimer toutes les lignes vides

sed  '/^$/d'

Supprimer tous les commentaires

sed '/^#/d' config.txt > config1.txt
«^» signifie début de ligne 
«#» est le début d'une ligne commentée.
Le «d» signifie de ne pas afficher les lignes contenant la recherche dans la sortie.
Inscrire le résultat dans le fichier config1.txt.

Supprimer toutes les lignes contenant un mot

sed '/mot/d'
sed -e '/mot1/;/mot2/d'

Supprimer toutes les lignes d'un mot à un autre

sed '/mot1/,/mot2/d'

Ressources complémentaires sur sed

 Source : https://doc.ubuntu-fr.org/sed
 Source : https://www.shellunix.com/sed.html
 Source : 31 exemples : https://likegeeks.com/sed-linux/
 Source : https://buzut.net/la-commande-sed-pour-les-nazes/
 Source : https://linux.developpez.com/faq/?page=La-commande-sed
 Source : https://www.system-linux.eu/index.php?post/2008/12/21/La-commande-Sed
 Source : http://web.archive.org/web/20160311044420/https://supersonique.net/administration/rechercher-et-remplacer-en-ligne-de-commande-bash-shell-sed/

Opérateurs de comparaison

Source : https://abs.traduc.org/abs-5.3-fr/ch07s03.html

Tester si un script est lancé en tant que root

if [ "$(whoami)" != root ];
then
 echo "$(whoami) n'est pas root. Relancer le script en tant que root !"
 sleep 4
 exit 1
fi

Tester une chaîne de caractères

ID_table_affiliation=50
Allemagne=DE

# Soit en utilisant if.
if [ $Allemagne = "DE" ]
then
echo "DE est bien le code de l'Allemagne."
else
echo "La variable ne correspond pas.";
fi

# Soit en utilisant grep.
if echo "$Allemagne" | grep "DE" >/dev/null 2>&1;
then
echo "DE est bien le code de l'Allemagne."
else
echo "La variable ne correspond pas.";
fi

Tester un dossier ou un fichier

Tester si un dossier existe

# Vérifier si le dossier d'installation existe, sinon, le créer.
ABS_PATH_INSTALLEUR=$(readlink -e ~/installeur)
if [ -d "$ABS_PATH_INSTALLEUR" ]; then
 echo " Le dossier ~/installeur existe déjà "
 sleep 3
else
 echo " Le dossier ~/installeur va être créé "
 sleep 3
 mkdir $ABS_PATH_INSTALLEUR
fi

Tester si un fichier existe sinon le créer

if [ -f "menu.sh" ]; then
echo " Le fichier du menu existe "
sleep 3
else
echo " Le fichier du menu n'existe pas encore et va être créé "
sleep 3
exit
fi
# test -d => teste l'existence d'un dossier (un fichier de type "d" )
# test -f => teste l'existence d'un fichier (fichier de type "-" )
# test -L => teste l'existence d'un lien symbolique (fichier de type "l" )
# test -s => teste l'existence d'un socket (fichier de type "s" )
# test -b => teste l'existence d'un fichier I/O en mode bloc (fichier de type "b" )
# test -c => teste l'existence d'un fichier I/O en mode caractère (fichier de type "c" )
# test -e => teste l'existence d'un fichier quel que soit son  
# type mais ne fonctionne qu'en bash. Pour faire pareil en "sh" (vieux Unix), il faut faire "ls -d <fichier> 1>/dev/null 2>&1"
# Petit danger => "test -d" sur un lien symbolique vers un dossier renvoie "vrai" (le test s'applique sur la cible du lien et non sur le lien lui-même).
# Si on veut tester que le fichier est un vrai répertoire, il faut faire un test de ce type # test -d dossier -a ! -L dossier

Tester si un fichier existe sinon le créer

#!/bin/bash
if [ ! -f ~/.hello ]; then
echo "Hello World !">~/.hello
fi
# Afficher le contenu Hello World !
cat ~/.hello

Utiliser une pause entre deux commandes

Mettre pause avec sleep

# Waits 0.5 second.
sleep .5
# Mettre en pause un script pendant une minute.
sleep 60
sleep 60s
sleep 1m
# Waits 5 hours.
sleep 5h
# Waits 5 days.
sleep 5d

Mettre pause avec read

read -p "Pause Time 5 seconds" -t 5
read -p "Continuing in 5 Seconds...." -t 5
echo "Continuing ...."
 Tutoriel complémentaire pour utiliser read : http://www.quennec.fr/trucs-astuces/syst%C3%A8mes/gnulinux/programmation-shell-sous-gnulinux/les-bases-de-la-programmation-shell/la-commande-read

Mettre pause avec read

echo "Appuyer sur une touche pour continuer..."
read a

Ou encore :

read -p "Appuyer sur une touche pour continuer..."

Mettre pause avec read

#! /bin/bash

echo "Appuyer la touche <Entrée> pour continuer..."
read touche
case $touche in
*)	echo "Reprise du script..."
	;;
esac

Mettre pause avec read

#! /bin/bash

echo "Voulez-vous continuer ? [O/N]"
read mot
while
[ "$mot" = "O" ]
do
echo "Voulez-vous continuer ? [O/N]"
read mot
done
echo "Programme achevé..."

Récupérer une variable avec read

echo "Renseigner le chemin du site sur le modèle /var/www/site";
echo "Le programme est en attente de la saisie :";
read chemin_site

echo "Le chemin du site est : $chemin_site";
Source : https://fr.wikibooks.org/wiki/Programmation_Bash/Interactions_avec_l%27utilisateur
Source : http://blog.inforeseau.com/2010/11/ecrire-script-bash-interactif-avec-saisie-par-lutilisateur

Utiliser des couleurs dans le shell

# Déclarer les couleurs
noir='\e[0;30m' gris='\e[1;30m' rougefonce='\e[0;31m' rose='\e[1;31m' vertfonce='\e[0;32m' vertclair='\e[1;32m' orange='\e[0;33m' jaune='\e[1;33m' bleufonce='\e[0;34m' bleuclair='\e[1;34m' violetfonce='\e[0;35m' violetclair='\e[1;35m' cyanfonce='\e[0;36m' cyanclair='\e[1;36m' grisclair='\e[0;37m' blanc='\e[1;37m' neutre='\e[0;m'
# Utiliser la couleur
# N'oublies pas le "-e" pour la commande "echo" sans quoi les caractères d'échappement ne seront pas interprétés ;-\
# Si echo -e ne fonctionne pas, tenter avec /bin/echo -e 
echo -e "${rougefonce}Bonjour${neutre} ${jaune}les gens${neutre}"
 Plus d'informations sur les couleurs et la mise en forme avec shell : https://www.admin-linux.fr/bash-de-la-couleur-dans-le-shell/

Passer root dans un script et poursuivre l’exécution

# On ne peut pas passer root dans un script et poursuivre l'exécution du script en tant que root.
# su, sudo, etc. sont des commandes externes, exécutées dans un autre processus.
# Elles ne peuvent donc pas changer l'uid du script en cours (Le process père).
# Passer les commandes à exécuter en root comme étant des arguments de la commande "su" ou "sudo".

# A la demande du mot de passe, c'est le mot de passe root qu'il faut saisir.

# Passer en root.
su -c '
# Tes commandes à lancer en tant que root, exemple avec le chargement d'une image Docker.
docker load -i /home/user/image.tar
'

# La suite du script.
## Ici du code.

Boucles

Test conditionnel avec if

if [ $? = 0 ]
then
# echo "Oui !"
retour="0"
else
# echo "Non !"
retour="1"
fi

Test conditionnel avec for

MAX=2
for X in $(seq 1 $MAX) ; do
commande
done
Source : https://www.cyberciti.biz/faq/bash-for-loop/
Source : https://www.tutorialspoint.com/unix/unix-loop-control.htm

Test conditionnel avec while

# Initialisation de la boucle.
Var="0"
while [ $Var = 0 ]
do

# La boucle permet de répéter l'action d'ajouter différents canal web tant que la variable réponse est égale à la valeur oui, oui pour ajouter des références supplémentaires.
Question=$(zenity --question \
		--title="Ajouter d'autres liens ?" \
		--ok-label="Oui" \
		--cancel-label="Non" \
		--text="Ajouter d'autres liens ?" 2>/dev/null
);

# Tester le retour de la réponse à la question.
# Si on choisit la réponse Oui, la valeur 0 est retournée.
if [ $? = 0 ]
then
echo "Le choix est Oui !"
Var="0"
else
echo "Le choix est Non !"
Var="1"
fi

echo "Test de la variable Var en fin de script $Var"

done

Barre de progression

Source : https://github.com/adriano-pinaffo/progressbar.sh

Question Réponse

Oui ou Non

echo -n "Continuer le programme pour modifier les droits CHMOD ?"
echo "Saisir 'O' ou 'o' pour continuer. 'N' ou 'n' pour arrêter.";
read answer
if [ "$answer" != "${answer#[Oo]}" ] ;then
    echo Oui
else
    echo Non
fi
Source : https://www.it-swarm.net/fr/linux/comment-demander-une-entree-oui-non-annuler-dans-un-script-linux-shell/958436319/

Question réponses multiples

read -p "Éteindre, Redémarrer ou Annuler (e/r/a) :" ans ;

case $ans in
   e|E)
       sudo poweroff;;
   r|R)
       sudo reboot;;
   *)
       exit;;
esac

Question réponses multiples

echo "Appuyer sur "j" pour modifier les CHMOD de Joomla.";
echo "Appuyer sur "m" pour modifier les CHMOD de Mediawiki.";
echo "Appuyer sur "w" pour modifier les CHMOD de WordPress.";
echo "Appuyer sur "a" ou toutes autres touches pour arrêter le programme.";
# echo "Appuyer sur "z" pour modifier les CHMOD de Autre CMS.";
read -p "Sélectionner le CMS utilisé :" ans ;

case $ans in
   j|J)
       echo "Joomla";
       ;;
   m|M)
       echo "Mediawiki";
       ;;
   w|W)
       echo "Wordpress";
       ;;
   #z|Z)
   #    echo "Autre CMS";
   #    ;;
   *)
       echo "Arrêter le programme";
       ;;
esac

Créer un menu à choix multiples

#!/bin/bash
echo " ################################## "
echo " #          Choix du menu         # "
echo " #    Installation automatique    # " 
echo " ################################## "
echo
echo " Cet assistant installe, configure ou supprime vos paquets automatiquement. "
echo
echo " [1] Installer Docker "
echo " [2] Supprimer Docker "
echo " [3] Supprimer les conteneurs et les images de Docker "
echo " [4] Importer l'image Docker de Debian "
echo " [5] Exit "
echo
echo "Choisir une option pour continuer :"

read person
case "$person" in

# "1" | "un" | "UN" | "Un" valeurs acceptées pour lancer ce menu.
  "1" | "un" | "UN" | "Un" )
  echo
  echo " Installer Docker "
  echo " Ajouter les commandes "
  sleep 4
  ;;
# Double points virgule pour fermer chaque option.

# "2" | "deux" | "DEUX" | "Deux" valeurs acceptées pour lancer ce menu.
  "2" | "deux" | "DEUX" | "Deux" )
  echo
  echo " Supprimer Docker "
  echo " Ajouter les commandes "
  sleep 4
  ;;
# Double points virgule pour fermer chaque option.

# "3" | "trois" | "TROIS" | "Trois" valeurs acceptées pour lancer ce menu.
  "3" | "trois" | "TROIS" | "Trois" )
  echo
  echo " Supprimer les conteneurs et les images de Docker "
  echo " Ajouter les commandes "
  sleep 4
  ;;
# Double points virgule pour fermer chaque option.

# "4" | "quatre" | "QUATRE" | "Quatre" valeurs acceptées pour lancer ce menu.
  "4" | "quatre" | "QUATRE" | "Quatre" )
  echo
  echo " Importer l'image Docker de Debian "
  echo " Ajouter les commandes "
  sleep 4
  ;;
# Double points virgule pour fermer chaque option.

# "5" | "cinq" | "CINQ" | "Cinq" valeurs acceptées pour lancer ce menu.
  "5" | "cinq" | "CINQ" | "Cinq" )
  echo
  echo " EXIT "
  echo " L'assistant pour une installation automatique va s'arrêter. "
  echo " Utiliser la commande sh menu.sh pour relancer l'assistant. "
  sleep 4
  exit
  ;;
# Double points virgule pour fermer chaque option.

          * )
  # Réponse par défaut.
  echo "Ce choix n'est pas disponible."
  sleep 2
  echo
  echo "Merci d'utiliser uniquement les options du menu."
  sleep 3
  sh menu.sh
  ;;

esac
exit 0

Lancer une commande si le terminal est fermé avec la croix

# Simuler un installateur classique :
#!/bin/bash
set -e
set -v

# Creating an installation directory with a unique name,
# to avoid concurrency issues.
INSTALLDIR="$(mktemp -d installdir.XXXXXX)"

# Setting up cleanup of the installation directory on
# exit.  WARNING: do not use `cd` in the script, as
# INSTALLDIR is a relative path.
clean-installdir () {
rm -r "$INSTALLDIR"
}
trap clean-installdir EXIT

# Installing...
printf "Installation in progress in %s\n" "$INSTALLDIR"
# The sleeping simulates the time it would take for a
# real installation to occur.  You can close the program
# in any way you wish, to do some tests, in this time
# frame.
sleep 10

# Everything went well for the script
printf "%s\n" "Done."

# Note that you should see execution of clean-installdir
# here, as the program is exiting.  
Si je ferme le programme à coup de <C-c>, ou si je clos la fenêtre avec le raccourci clavier de mon gestionnaire de fenêtre, le répertoire d'installation est effacé.
Si je laisse le programme s'exécuter jusqu'au bout, c'est aussi le cas sans appeler explicitement la fonction.
Si je ferme la fenêtre de mon terminal avec le programme xkill, le script reçoit un signal KILL impossible à capter.
Par conséquent, le répertoire d'installation reste présent à côté du script, et doit être effacé manuellement.
Complément : http://www.commandeslinux.fr/arreter-un-programme-qui-a-bogue-sous-linux/
Intercepter un signal pour interdire certaines commandes : http://techno.firenode.net/article.sh?id=d2016080407535785187
Il se peut que certains gestionnaires de fenêtres aient ce genre de comportement pour lutter contre les fenêtres récalcitrantes.
Seul le manager de fenêtre dwm a été testé mais il y en a d'autres : xfwm4, metacity, kwin, awesome, fvwm, openbox...

Créer un fichier temporaire avec mktemp

# Créer un fichier texte aléatoire tmp.EAL1UAauCn dans le dossier /tmp/ et ajouter le résultat de la commande ls.
OUT="$(mktemp)"
ls > $OUT
# Créer un fichier temporaire et ajouter la date du jour.
# Le modèle peut être n'importe quel nom de fichier avec un certain nombre de 'X' ajoutés.
OUT=$(mktemp /tmp/output.XXXXXXXXXX) || { echo "Failed to create temp file"; exit 1; }
echo "Today is $(date)" >> $OUT
Plus d'informations avec man page mktemp

Variable d'environnement TMPDIR

# Par défaut, mktemp utilisera $TMPDIR de l'utilisateur.
# S'il n'est pas défini, il utilisera /tmp.
# Vous pouvez utiliser le répertoire spécifié en tant que préfixe lors de la génération du nom de fichier temporaire.
# Le répertoire sera remplacé par la variable d'environnement TMPDIR de l'utilisateur s'il est défini.
# Dans cet exemple, le fichier temporaire sera créé dans /chroot/apache/var/tmp à moins que la variable d'environnement TMPDIR de l'utilisateur ne spécifie le contraire.
mktemp -p /chroot/apache/var/tmp php.lock.XXXXXXXXXX

Créer un compte à rebours

Source : http://nuxadmin.blogspot.fr/2011/10/bash-script-compte-rebours.html

Bibliographie

 Source : https://doc.ubuntu-fr.org/tutoriel/script_shell
 Source : http://www.dreamsyssoft.com/unix-shell-scripting/ifelse-tutorial.php
 Introduction à Shell Bash : https://ensiwiki.ensimag.fr/index.php?title=Introduction_aux_scripts_shell
 Les tests avec Bash : https://fr.wikibooks.org/wiki/Programmation_Bash/Tests
 Source : https://linuxfrench.wordpress.com/2017/03/07/4-ligne-de-commande-scripts-shell/
 Source : https://buzut.fr/101-commandes-indispensables-sous-linux/

Programmation avancée avec Bash

 Debian Admin - Advanced Bash-Scripting Guide : http://www.debianadmin.com/advanced-bash-scripting-guide.html
 Advanced Bash-Scripting Guide : Revision 10 - 10 Mar 2014 : http://www.tldp.org/LDP/abs/abs-guide.pdf
 Bash scripting Tutorial : https://linuxconfig.org/bash-scripting-tutorial
 Guide avancé d'écriture des scripts Bash : https://abs.traduc.org/abs-fr/
 Les scripts bash : http://blaireaulinux.free.fr/linux-scripts-bash-1.php
 ABS-Guide : https://linux.die.net/abs-guide/

Utiliser des commandes Shell avec le terminal

Utiliser des commandes Shell avec le terminal est un pense bête pour administrer GNU/Linux.

Utiliser Zenity

Utiliser Zenity

NAVIGATION

PARTICIPER ET PARTAGER

Bienvenue sur le wiki de Amis SH.
De nombreuses pages sont partagées sur ce wiki.
Créer un compte utilisateur pour participer sur le wiki.
Les pages présentées sur le wiki évoluent tous les jours.
Certaines recherches sont peu abouties et incluent des erreurs.
Utiliser la recherche interne du wiki pour trouver votre contenu.
La page de discussion de Amis SH vous permet de poser vos questions.
Consulter le site amis-sh.fr pour installer votre propre serveur web.
Améliorer le contenu des pages avec vos retours depuis l'onglet discussion.
Ce contenu ne doit pas servir à nuire à autrui ou à un système informatique.
Protéger votre système Linux ou Windows avec cette page dédiée à la sécurité.

SOUTENIR CE WIKI

Soutenir le wiki avec un don en monnaie numérique :
AEON - Bitcoins - Bitcoins Cash - Bitcoins Gold - Bitcore - Blackcoins - Basic Attention Token - Bytecoins - Clams - Dash - Monero - Dogecoins - Ğ1 - Ethereum - Ethereum Classique - Litecoins - Potcoins - Solarcoins - Zcash

OBTENIR DE LA MONNAIE NUMERIQUE

Obtenir gratuitement de la monnaie numérique :
Miner de la cryptomonnaie.