# Astuces Bash ~~~ function hello { echo Hello; echo $1; } ~~~ ## Raccourcis ~~~ Ctrl+d : quitte le terminal courant / supprime le caractère sous le curseur si la ligne n'est pas vide Ctrl+h : supprime le caractère avant curseur Ctrl+a : aller en début de ligne Ctrl+e : aller en fin de ligne Ctrl+k : effacer (coupe) du curseur à la fin de la ligne Ctrl+u : effacer (coupe) du début de ligne au curseur Ctrl+y : colle la partie précédemment coupée Ctrl+r : rechercher parmi l'historique Ctrl+s : freeze l'affichage de l'output Ctrl+q : défreeze l'affichage de l'affichage de l'output Ctrl+t : inverse les caractères autour du curseur Ctrl+c : annule la ligne en cours et passer sur une nouvelle ligne vide Ctrl+z : suspend la tâche en cours ctrl+l : efface/rafraichit l'écran ctrl+w : efface le mot qui précède le curseur jusqu'au séparateur de mot (une espace en général) ctrl+x ctrl+e : édite la ligne dans $VISUAL ou $EDITOR si non définie alt+effacer : Efface un mot à gauche du curseur alt+d : Efface un mot à droite du curseur alt+t : Inverse les deux mots à gauche du curseur ~~~ ## Traduire les espaces insécables en espaces Dans le fichier `~/.inputrc` : ~~~ # espace insécables et espaces fine insécables -> espace "\xc2\xa0": " " "\xe2\x80\xaf": " " ~~~ ## Rendre la complétion insensible à la casse Dans le fichier `~/.inputrc` : ~~~ set completion-ignore-case On ~~~ # Script ## Variables ### Environnement ~~~{.bash} $PPID $BASHPID $! $$ $PIPESTATUS ~~~ ### Initialiser ~~~{.bash} var= ~~~ En readonly <=> constante ~~~{.bash} readonly var="pas touche" ~~~ ### Protéger ~~~{.bash} [ -n "${var}" ] && true #et surtout pas [ -n $var ] && false #car si var est vide, l'expression sera équivalente à [ -n ] => erreur de syntaxe ~~~ ~~~{.bash} echo $var "joue au ${foo}t" #et surtout pas echo $var "joue au $foot" #car sinon c'est bien le contenu de la variable $foot qui sera remplacé et non $foo ~~~ ## Conditions ~~~{.bash} true && echo "C'est toujours vrai" false || echo "Ça sera toujours vraiment faux" [ $? -eq 0 ] && { echo "tâche"; sleep 1; echo -e "\e'a plus!!" } ~~~ ### test ## Boucles «Liste» : ~~~{.bash} for i in "valeur1 valeur2prisavec1" valeur3 valeurn; do echo $i; done ~~~ «Incrémentale» : ~~~{.bash} for ((i=0; i<10; i++)); do echo $i; done #ou for i in $(seq 1 10); do echo $i; done #ou for i in {1..10}; do echo $i; done ~~~ «Conditionnelle» : ~~~{.bash} file=; while [ -f "$file" ]; do sleep 10; touch $file; done ~~~ ## Processus ~~~{.bash} ( echo "Je suis un fils du script principal, mais on attend que je meurs."; exit 0; ) ( echo "Libreee !"; yes "Libre je dis !"; ) & sleep 10 && kill $! #on tue le dernier fils créé ~~~ > Note: Dans une boucle, ne pas créer de process via *(* *)* sinon un usage comme **break** ou **continue**, ... ne fonctionnera pas : > > ~~~{.bash} > while : > do > : && { echo "Stop !"; break; } > done > # ( echo "Stop !"; break; ) dans cet exemple ne quittera pas la boucle -car break dans un process fils-, et donc restera infini > ~~~ ## Astuces [concrètes] ### Récupérer tout stdin dans une variable #### Complet ~~~{.bash} var="$(cat <&0)" #ou var="$(cat -)" ~~~ #### Ligne par ligne ~~~{.bash} var= while read ligne do var="${var}${ligne}" done <&0 ~~~ autrement : ~~~{.bash} cat <&0 | (while read ligne; do ... done) ~~~ ### Écrire un fichier temporaire [unique] ~~~{.bash} nomfichier=$(mktemp) #pour un répertoire nomrep=$(mktemp -d) ~~~ > Note: La création d'un fichier temporaire n'implique pas côté système une suppression automatique de ce dernier. ### Gérer arguments donné au script Exemple : ~~~{.bash} #!/bin/bash DELAY= NUMARG=0 FICHIER= while : do [ $# == 0 ] && break OPTIND=1 while getopts ":d:n" opt "$@" do case "$opt" in d) DELAY=$OPTARG; (( NUMARG+=1 )) ;; n) NOMAIL=true; (( NUMARG+=1 )) ;; :) >&2 echo "Manque un argument avec cette option." ;; *) >&2 echo "$0 [-d DELAY] [-n] [FILE]"; exit 1 ;; esac done shift $((OPTIND-1)) #Savoir si après toutes les options, une chaîne de caractère présente pour FILE [ -z "$1" ] && break #FICHIER=$1 si FICHIER non initialisé [ -z "$FICHIER" ] && FICHIER=$1 || { >&2 echo "Fichier en trop."; break; } shift done echo echo "==RESULTAT==" echo "ARG " $NUMARG echo "FICHIER=" $FICHIER echo "DELAY=" $DELAY echo "NOMAIL=" $NOMAIL exit 0 ~~~ Permettra par exemple : ~~~ ./cmd -d 2 -n monfichier ./cmd -d2 monfichier ./cmd monfichier -d 2 -n ./cmd -n monfichier -d2 ~~~ ### Passer arguments de facon optionelle ${var:+..} peut etre utile ~~~{.bash} $ in_uid=1009 in_login=app_user adduser \ --gecos "User $in_login" \ --disabled-password "$in_login" \ ${in_uid:+'--uid' "$in_uid"} ~~~ ### Lire les commandes intégrés dans BASH #### Lister fonctions ~~~{.bash} $ typeset -F $ typeset -f #pour lister contenu de la fonction avec ~~~ #### Voir contenu ~~~{.bash} $ type FUNCTION ~~~ Pour ceux «built-in», pas possible : ~~~{.bash} $ type getopts getopts is a shell builtin ~~~ ## Utiliser résultat xargs en milieu de commande ~~~{.bash} $ echo coucou | xargs -i echo {} c\'est moi! ~~~