Shell
La maitrise d'un shell Unix offre une puissante interface de contrôle des systèmes. Les shells permettent de rédiger à la volé des chaînes de commandes que votre expérience rendra de plus en plus complexe à mesure que vous découvrirez les options de chacunes d'elles. Avec le temps, la rédaction de script shell vous permettra de ne plus devoir exécuter manuellement des tâches ennuyeuses et répétitives.
Toutes la puissance et la simplicité de Linux réside dans l'utilisation conjointe d'une interface graphique efficace, c'est à dire adaptée à votre philosophie de travail et à vos goûts, et d'un shell maitrisé pour automatiser tout ce qui peux l'être.
Shell Script
Un script est un simple fichier texte contenant les commandes que vous auriez normalement saisi dans un terminal, séparées par des retour à la ligne. Une fois la suite de commande saisie, l'exécution du script se fait en demandant au shell de lire le fichier. Exemple :
bash mon_script.txt
bash mon_autre_script.sh
perl mon_super_script.pl
python mon_ultime_script.nimp
Sous Linux, l'extension d'un fichier n'a aucune incidence. Elles n'ont d'intérêt que pour le confort de l'utilisateur
Pour ne pas avoir à appeler sois-même l'interpréteur d'un script, dans un premier temps il faut rendre le fichier exécutable :
chmod +x mon_script.txt
chmod 755 mon_autre_script.sh
Puis, pour que le shell sache quel interpréteur de commande utiliser d'un script à l'autre, il faut ajouter sur la première ligne du script un chi-bang : #!
Ce marqueur permet d'indiquer quel binaire du système doit interpréter un script. Exemple :
#! /bin/bash
#! /bin/sh
#! /usr/bin/php
Face à la diversité des Unix qui ne choisissent pas toujours de mettre les binaires (fichier exécutable) aux mêmes endroits, il a été décidé de confier à la commande env la recherche des environnements d'exécutions. Cette commande est toujours placé dans /usr/bin/. Ainsi les scripts doivent désormais commencer par :
#! /usr/bin/env bash
#! /usr/bin/env sh
#! /usr/bin/env php
Avantage supplémentaire : il est possible dans certain cas d'indiquer une version d'environnement afin d'éviter les problèmes de dépréciation :
#! /usr/bin/env python3
Note: lancé seul dans un terminal, la commande env affichera l'ensemble des variables d'environnements.
Bash
Le Bourne Again SHell (bash) et le successeur du Bourne SHel (bsh). Il s'agit du shell majoritairement utilisé par les distributions Linux.
Il dispose d'un langage interprété permettant de déclarer des fonctions, des boucles, des variables, etc.
Affectation de variable
var=valeur
pas d'espace avant ou après le « = » !
Lecture de variable
echo $var
Ainsi :
- l'affectation se fait sans le caractère « $ »
- la lecture se fait avec le caractère « $ » devans le nom de la variable.
Test
if test ; then instruction ; fi
if test ; then instruction ; else instruction ; fi
Boucle
for var in valeur1 valeur2 [...] valeurX ; do instruction ; done
while test ; do instruction ; done
etc... https://fr.wikipedia.org/wiki/Bourne-Again_shell
Exemple sur le client Ubuntu : vi /home/user/kikoo
#! /usr/bin/env bash
function readnum {
# Lecture d'un nombre entier
printf "Entrer un numéro entier svp [0-999]: "
read -r num
# Vérification que c'est un entier
num=$(echo "$num" | grep -E '^[0-9]*$')
# Relance si ce n'est pas un entier
if [ -z "$num" ]; then
printf "Tu dois entrer un entier b**let\n"
readnum
fi
}
# Appel de la fonction
readnum
# Evite une valeur trop grande
if [ "$num" -gt 99 ]; then
# Evite une valeur vraiiiment trop grande
if [ "$num" -gt 999 ]; then
printf "Je vais me pendre... x_x\n"
exit 2
fi
for i in $(seq 1 "$num"); do
printf "b**let! "
done
printf "\n"
exit 1
fi
# Affichage sequentiel
for i in $(seq 1 "$num"); do
printf "%s kikoooo :o)\n" "$i"
sleep 0.1
done
exit 0
Pour tester le script il faut en premier lieu lui donner le droit d'exécution :
chmod +x kikoo
Puis, pour exécuter un script local (qui n'est pas dans le PATH) il faut indiquer son adresse complète :
/home/$USER/kikoo
Pour éviter celà, si l'on se trouve dans le répertoire du script, il suffit d'utiliser l'alias « . » qui représente le répertoire courrant :
./kikoo
Alias de chemin
Sous Unix/Linux, des alias permettent de raccourcir les adresses :
- / : la racine du système
- . : le répertoire courant
- .. : le répertoire parent du répertoire courant
- ~ : le répertoire de l'utilisateur
- - : le répertoire précédent (avant le dernier cd)
Raccourcis clavier
Déplacement
- Ctrl + A : aller au début de la ligne
- Ctrl + E : aller à la fin de la ligne (End)
- Ctrl + F : aller un caractère en avant (Forward)
- Ctrl + B : aller un caractère en arrière (Backward)
- Alt + B : aller un mot en arrière (Backward)
- Alt + F : aller un mot en avant (Forward)
- Ctrl + XX : aller et revenir entre le début de la ligne et la position actuelle du curseur
- Ctrl + L : vider le terminal
Historique
-
Ctrl + P : afficher la commande précédente dans l’historique (Previous)
-
Ctrl + N : afficher la commande suivante dans l’historique (Next)
-
Alt + < : aller au début de l’historique
-
Alt + > : aller à la fin de l’historique
-
Ctrl + R : rechercher une commande (Reverse)
- ensuite il suffit de commencer à écrire les caractères de la commande en question
- Ctrl + R : remonter dans l’historique de recherche
- Ctrl + S : redescendre dans l’historique de recherche, si ce n’est pas déjà utilisé par le contrôle de flux, ce qui est généralement le cas (Search)
- Ctrl + G : quitter la recherche sans rien exécuter
-
Alt + R : annuler les changements en cours dans une commande de l’historique (Revert)
-
Ctrl + Alt + Y : insérer le premier argument de la commande précédente (Yanking)
-
Alt + . ou Alt + _ : insérer la dernière chaîne de caractères de la commande précédente
- répéter la commande pour remonter dans l’historique
Modification
-
Ctrl + U : supprimer avant le curseur jusqu’au début de la ligne
-
Ctrl + K : supprimer depuis le curseur jusqu’à la fin de la ligne (Killing)
-
Ctrl + W : supprimer avant le curseur jusqu’au début de la chaîne
-
Alt + D : supprimer depuis le curseur jusqu’à la fin de la chaîne
-
Ctrl + Y : restaurer ce qui a été supprimé avec l’une des combinaisons (Yanking)
- Alt + Y : remonter de l’historique du « kill ring » et ainsi restaurer d’anciennes suppressions
-
Ctrl + D : supprimer le caractère sous le curseur, comme Suppr
-
Ctrl + H : supprimer le caractère avant le curseur, comme Retour
-
Ctrl + J ou Ctrl + M : valide la commande, comme Entrée
-
Alt + U : mettre en majuscule depuis le curseur jusqu’à la fin de la chaîne (Uppercase)
-
Alt + L : mettre en minuscule depuis le curseur jusqu’à la fin de la chaîne (Lowercase)
-
Alt + C : mettre en majuscule le caractère sous le curseur (Capitalize)
-
Alt + T : inverser les deux chaînes avant le curseur (Transpose)
-
Ctrl + T : inverser les deux derniers caractères depuis le curseur (Transpose)
-
Alt + # : insérer un # au début de la ligne et valider
- ça revient à insérer un commentaire dans l’historique de bash
-
Ctrl + V : fait que le prochain caractère tapé est inséré en « Verbatim »
- faites Ctrl + V et appuyer Entrée en suite pour voir ce que ça fait concrètement, ça peut servir pour insérer une tabulation par exemple
-
Ctrl + Insert ou Ctrl + Shift + C : copier
-
Shift + Insert ou Ctrl + Shift + V : coller
- l’avantage de la combinaison avec Insert c’est qu’elle fonctionne partout
Complétion
-
Tab : compléter l’élément (commande, chemin, arguments) sous le curseur
-
Alt + ? : afficher les complétions possibles
-
**Alt + *** : insérer toutes les complétions possibles
-
Ctrl + X ( : commencer l’enregistrement d’une macro
-
Ctrl + X ) : terminer l’enregistrement d’une macro
-
Ctrl + X E : exécuter la macro précédemment enregistrée
Divers
-
Ctrl + C : arrêter la commande en cours
-
Ctrl + Z : suspendre le programme en cours
- il faut saisir la commande fg (foreground) pour reprendre le programme
-
Shift + PgUp : faire défiler vers le haut une « page »
-
Shift + PgDn : faire défiler vers le bas une « page »
-
Ctrl + Shift + Haut : faire défiler vers le haut une ligne
-
Ctrl + Shift + Bas : faire défiler vers le bas une ligne
Pour en savoir plus
man -P 'less -p ^READLINE' bash
man -P 'less -p ^EDITING' readline
IFS
IFS (Internal Field Separator) est une variable d'environnement qui définie les caractères servant de séparateur d'argument. En général, l'IFS contient par défault les caractères espace, tabulation et nouvelle ligne. Vous pouvez le visualiser comme suis :
printf "%q\n" "$IFS"
$' \t\n'
Note : le marqueur %q de la fonction printf imprime l'argument associé avec les caractères spéciaux « échapé » de sorte qu'une chaîne soit réutilisable en entrée d'une autre commande...
Autrement dit, durant l'interprétation d'une commandes, le shell traitera ces caractères comme des marqueurs de séparation. Exemple :
mkdir test
touch 'un fichier' 'un autre fichier' 'un dernier fichier'
for i in $(ls *); do echo "Match: $i"; done
Match: un
Match: autre
Match: fichier
Match: un
Match: dernier
Match: fichier
Match: un
Match: fichier
IFS=$'\n'
for i in $(ls *); do echo "Match: $i"; done
Match: un autre fichier
Match: un dernier fichier
Match: un fichier
Manipuler l'IFS permet de grandement simplifier certain traitement :
for i in $PATH; do echo "Match: $i"; done
Match: /home/user/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
IFS=':'
for i in $PATH; do echo "Match: $i"; done
Match: /home/user/bin
Match: /usr/local/sbin
Match: /usr/local/bin
Match: /usr/sbin
Match: /usr/bin
Match: /sbin
Match: /bin
var="a,b,c,d"
IFS=","
printf "%s\n" $var
a
b
c
d
Attention, le caractère « espace » est traité de façon spécial :
var="a-b---c-d"
IFS='-'
for i in $var; do echo -n "[$i]"; done; echo
[a][b][][][c][d]
var="a,b,,,c,d"
IFS=','
for i in $var; do echo -n "[$i]"; done; echo
[a][b][][][c][d]
var="a b c d"
IFS=' '
for i in $var; do echo -n "[$i]"; done; echo
[a][b][c][d]
# Noter l'absence de [] vide. Contrairement aux autres caractères, les espaces sont agrégé.
