====== Shell ======
----
===== Sécurisation exécution =====
==== set ====
| set -o pipefail | Permet de retourner une erreur quand la première partie d'un pipe est en erreur |
| set -o errexit (ou set -e) | Force l'arrêt du script en cas d'erreur d'une commande |
| set -o nounset (ou set -u) | Sort en erreur si une variable est utilisée sans avoir été déclarée préalablement |
| set -o errtrace (ou set -E) | |
| set -x | Mode debug, chaque ligne est affichée lors de l'exécution |
----
===== Variables =====
==== Paramètres ====
| $0 | Nom de la commande en cours d'exécution (ou shell courant) |
| $1..$9 | Arguments de la ligne de commande ou de la procédure en cours |
| $# | Nombre d'arguments |
| $* | Liste des arguments (sauf $0) en 1 seul argument en utilisant le séparateur $IFS ("$1 $2 $3 …$n") |
| $@ | Liste des arguments (sauf $0) en n arguments ("$1" "$2" "$3" …"$n") |
| Shift | Décale les arguments à gauche, $0 inchangé, $1 perdu, $2 passe dans $1… |
==== Entrées/Sorties ====
* 0 : entrée standard
* 1 : sortie standard
* 2 : sortie d'erreurs standard
=== Exemples ===
1>/dev/null : redirige vers la poubelle
2>/dev/null : redirige les erreurs vers la poubelle
1>&2 : redirige vers la sortie d’erreurs
==== Variables prédéfinies ====
| $? | Code de retour dernière commande (0 à 255). Code nul = vrai, sinon faux |
| $$ | Numéro de processus en cours d'exécution |
| $! | Numéro du dernier processus lancé en tâche de fond |
| $_ | paramètre le plus récent (ou le chemin abs de la commande pour démarrer le shell courant immédiatement après le démarrage) |
| $- | options actuelles définies pour le shell |
| $FUNCNAME | Nom de la fonction |
| $LINENO | Numéro de ligne |
| $IFS | Internal Field Separator (utile pour les boucles : IFS=$’\n’) |
| ~dp0 | Répertoire où se situe le script en cours d'exécution |
| %CD% | Répertoire courant |
[[https://www.gnu.org/software/bash/manual/html_node/Variable-Index.html|Index des variables]]\\
[[https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html|Paramètres spéciaux]]\\
[[https://www.gnu.org/software/bash/manual/html_node/Shell-Variables.html|Variables shell]]
=== Bash ===
| PS1 | Prompt par défaut de la ligne de commande |
| PS2 | Prompt pour les commandes sur plusieurs lignes suite à \. Par défaut affiche "> " sur les lignes suivantes |
| PS3 | Prompt pour les boucles select |
| PS4 | Prompt pour l'exécution en mode debug avec “set -x” |
| PROMPT_COMMAND | Commande exécuté juste avant l'affichage de la variable PS1 |
[[https://www.thegeekstuff.com/2008/09/bash-shell-take-control-of-ps1-ps2-ps3-ps4-and-prompt_command/]]
==== Alias ====
| \!* | désigne la liste des paramètres |
| %%\!^%% | désigne le premier paramètre |
| \!$ | désigne le dernier paramètre |
| \!:n | désigne le nième paramètre |
==== Tableaux ====
tableau[0]="truc"
tableau[1]="machin"
autre_tableau=("truc" "machin")
${#tableau[@]} indice du dernier élément du tableau (nombre éléments -1)
${!fruits[@]} donne la liste des indices du tableau (pour utilisation dans une boucle par exemple)
echo ${tableau[1]}
echo ${tableau[*]} # affiche tous les éléments
echo ${tableau[@]} # autre forme, même résultat
==== Calcul ====
Incrémenter de 1 la variable $var:
TOTO=`expr $var + 1`
let "var=var+1"
((var=var+1))
((var++))
==== Formatage ====
printf "%*s %*s %*s\n",$lng1,$var1,$lng2,$var2,$lng3,$var3
==== Shell parameter expansion ====
[[https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html]]
----
===== Manipulation de chaînes =====
==== Majuscule/Minuscule ====
texte_premiere_maj="${texte^}" # passe la première lettre en majuscule
texte_maj="${texte^^}" # passe la chaîne complète en majuscule
texte_premiere_min="${texte,}" # passe la première lettre en minuscule
texte_min="${texte,,}" # passe la chaîne complète en minuscule
==== Remplacement de caractère ====
=== ${variable//pattern/replacement} ===
# remplace ; par ,
modif_variable=${variable//;/,}
# enlever toutes les " dans une chaîne
modif_variable=${variable//\"/}
==== Extraire une sous chaîne ====
=== Exemples ===
var=banane
| %a* | plus petite chaîne commençant par a (ex : ${var%a*}=ban) |
| %%a* | plus grande chaîne commençant par a |
| #*a | plus petite chaîne terminant par a (ex : ${var#*a}=nane) |
| ##*a | plus grande chaîne terminant par a (ex : ${var##*a}=ne) |
=== Utilisation d'un séparateur ===
var="param1:param2"
IFS=:
set var
# var devient param1 param2
param1=$1
param2=$2
==== Expressions régulières ====
Les expressions régulières peuvent être utilisées avec bash depuis la version 3 en utilisant l'opérateur =~
=== Syntaxe ===
if [[ $VALEUR =~ regex ]]; then
echo "OK"
else
echo "KO"
fi
=== Capture ===
Les variables sont ${BASH_REMATCH[1]} à ${BASH_REMATCH[n]} au lieu de $1 à $n
=== Vérification expression régulière ===
[[https://regex101.com/]]
=== Source ===
[[https://fr.wikibooks.org/wiki/Programmation_Bash/Regex]]
==== Lire un fichier csv ====
# définir le séparateur , ou ;
IFS=,
while read -r colonne1 colonne2 colonne3; do
echo $colonne1
echo $colonne2
echo $colonne3
done < $fichier_csv
==== Construire une commande dans une variable ====
Pour construire une commande à exécuter dans une variable il faut utiliser un tableau pour éviter des problèmes avec les ' ou ".
# ne pas faire
USER="toto"
IP="192.168.0.1"
OPT="-o StrictHostKeyChecking=no"
CMD="$OPT $USER@$IP"
ssh $CMD
# utiliser un tableau à la place
CMD=(-o StrictHostKeyChecking=no toto@192.168.0.1)
ssh ${CMD[@]}
----
===== Tests =====
==== Opérateurs ====
| ! | négation d’une expression |
| -a | et logique |
| -o | ou logique (le et logique a une préséance plus grande) |
| \(expr\) | parenthèses pour regrouper les expressions (\ pour éviter interprétation) |
==== Fichiers ====
| -r | vrai si le fichier existe et accessible en lecture pour l’utilisateur |
| -w | vrai si le fichier existe et accessible en écriture pour l’utilisateur |
| -x | vrai si le fichier existe et accessible en exécution pour l’utilisateur |
| -f | vrai si le fichier existe et est un fichier normal |
| -d | vrai si le fichier existe et est un répertoire |
| -c | vrai si le fichier existe et est du type spécial caractère |
| -b | vrai si le fichier existe et est du type spécial bloc |
| -s | vrai si le fichier existe et a une taille non nulle |
| -L | vrai si le fichier est un lien |
| -e | vrai si fichier régulier ou lien |
==== Chaînes de caractères ====
| -z s1 | vrai si la chaîne s1 est de longueur nulle |
| -n s1 | vrai si la chaîne s1 contient au moins un caractère |
| s1=s2 | vrai si les 2 chaînes sont égales (attention aux blancs encadrant le signe %%=)%% |
| s1!=s2 | vrai si les 2 chaînes sont différentes |
| str | Vérifie si str n'est pas la chaîne vide; s'il est vide, il renvoie false |
==== Entiers ====
| -ne | différent | -eq | égal |
| -gt | supérieur | -lt | inférieur |
| -ge | supérieur ou égal | -le | inférieur ou égal |
----
===== Fonctions =====
==== Fichiers ====
| basename | extrait le nom du fichier après le dernier / |
| dirname | extrait le chemin d'accès avant le dernier / |
==== Mathématique ====
| + | Addition `expr a + b` |
| - | Soustraction `expr a - b` |
| * | Multiplication `expr a * b` |
| / | Division `expr a / b` |
| % | Modulo. Divise l'opérande de gauche par l'opérande de droite et renvoie le reste. `expr a % b` |
==== Saisie clavier : read ====
=== options ===
* -p : affiche un prompt
* -s : mode silencieux (n'affiche pas ce qui est tapé)
* -t : définit un délai d'expiration
* -a : stocke les entrées dans un tableau
* -n : limite le nombre de caractères à lire
* -r : mode raw (n'interprète pas les caractères d'échappement)
=== exemples ===
# lecture simple
echo "Entrez votre nom :"
read nom
echo $nom
# lecture avec prompt intégré
read -p "Entrez votre âge : " age
echo "$age"
# lecture silencieuse pour mot de passe
read -sp "Entrez votre mot de passe : " mdp
# Lecture avec délai d'expiration (en secondes)
read -t 5 -p "Vous avez 5 secondes pour répondre : " reponse
# Lecture de plusieurs variables
read -p "Entrez prénom et nom : " prenom nom
echo "Prénom : $prenom, Nom : $nom"
# Lecture d'un tableau
read -a tableau -p "Entrez plusieurs mots : "
echo "Premier mot : ${tableau[0]}"
echo "Deuxième mot : ${tableau[1]}"
----
===== Structures de contrôle =====
==== Prise de décision ====
=== if ===
if [ expression ]
then
Statement
else
Statement
fi
if [ expression 1 ]
then
Statement
elif [ expression 2 ]
then
Statement
elif [ expression 3 ]
then
Statement
else
Statement
fi
=== case ===
option="${1}"
case ${option} in
-f) FILE="${2}"
echo "File name is $FILE"
;;
-d) DIR="${2}"
echo "Dir name is $DIR"
;;
*)
echo "`basename ${0}`:usage: [-f file] | [-d directory]"
exit 1 # Command to come out of the program with status 1
;;
esac
==== Boucles ====
=== Boucle while ===
a=0
while [ $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
=== Boucle for ===
for var in 0 1 2 3 4 5 6 7 8 9
do
echo $var
done
for i in $(seq 0 9); do echo $i; done
fruits=("pomme" "orange" "banane" "fraise" "kiwi")
for fruit in "${fruits[@]}"; do
echo "Fruit: $fruit"
done
for (( i=0; i<${#fruits[@]}; i++ )); do
echo "Fruit $i: ${fruits[$i]}"
done
for index in "${!fruits[@]}"; do
echo "Fruit $index: ${fruits[$index]}"
done
=== Boucle until ===
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
=== Boucle sélection ===
Permet de créer un menu numéroté
PS3="Please make a selection => " # sans espace autour du signe =
select DRINK in tea cofee water juice appe all none
do
case $DRINK in
tea|cofee|water|all)
echo "Go to canteen"
;;
juice|appe)
echo "Available at home"
;;
none)
break
;;
*) echo "ERROR: Invalid selection"
;;
esac
done
=== Contrôle de boucle ===
| break | sort de l'exécution de la boucle. Possibilité d'indiquer un nombre pour sortir de plusieurs niveau de boucle |
| continue | passe à l'itération suivante de la boucle . Possibilité également de préciser un nombre pour indiquer un niveau supérieur de boucle |
==== Procédures/Fonctions ====
function maFonction()
{
...
}
maFonction()
{
...
}
Les deux syntaxes ont leur avantage :
* L'absence du mot-clé permet au script d'être compatible avec les shells Bourne et Korn.
* La présence du mot-clé permet d'éviter une collision de nom avec les alias.
----
===== Commandes =====
==== Nom de fichier ====
=== basename ===
Extraction du nom de fichier (ou repertoire) du chemin donné en entrée. En fait donne la chaîne après le dernier /.
=== dirname ===
Extraction de la partie répertoire du chemin donné en entrée
----
===== Astuces =====
==== Créer un fichier sans éditeur ====
cat << tagFIN > nomdufichier
....
...
tagFIN
----
===== Sources =====
* [[https://initscreen.developpez.com/tutoriels/batch/apprendre-la-programmation-de-script-batch/|Programmation batch]]
* [[http://ti1.free.fr/index.php/batch-manipulerles-chaines-de-caracteres/|Manipulation chaîne de caractères]]
----