HowtoBash
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
Initialiser
En readonly <=> constante
Protéger
[ -n "${var}" ] && true
#et surtout pas
[ -n $var ] && false
#car si var est vide, l'expression sera équivalente à [ -n ] => erreur de syntaxe
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
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» :
«Incrémentale» :
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» :
Processus
( 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 :
Astuces [concrètes]
Récupérer tout stdin dans une variable
Complet
Ligne par ligne
autrement :
Écrire un fichier temporaire [unique]
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 :
#!/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
$ 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
Voir contenu
Pour ceux «built-in», pas possible :
Utiliser résultat xargs en milieu de commande
Ajouter la complétion à un script
Pré-requis :
- La paquet
bash-completion
est installé.
Emplacement du script de complétion :
- Pour tout le système : le mettre dans un fichier dédié dans le
répertoire
/etc/bash_completion.d/
avec la permission644
. - Pour un utilisateur particulier : le mettre dans le
.bashrc
,.profile
ou autre fichier chargé à l’ouverture de la session de l’utilisateur. Si on a plusieurs fonctions de complétion, créer un.bash_completion
dédié et le sourcer dans le.bashrc
.
Dans le script de complétion, on appelle la commande Bash
complete
en lui indiquant une fonction avec l’option
-F
a appeler quand l’utilisateur appuie sur
tab
:
complete -F _MY_COMPLETION_FUNCTION PROG_NAME
Avant, on définit donc une fonction
_MY_COMPLETION_FUNCTION()
, qui doit remplir un array Bash
COMPREPLY=()
contenant les suggestions à présenter à
l’utilisateur.
On peut utiliser l’array COMP_WORDS
qui contient les
mots déjà écrits par l’utilisateur, et le nombre de mots déjà écrits
COMP_CWORD
.
Quand un mot est déjà partiellement écrit, on utilise la commande
Bash compgen
, qui va filter les mots à présenter en
fonction de celui déjà écrit.
Voici un exemple simple, qui répond
action1 action2 --option
après le nom du programme,
option1 option2
après -o|--option
et sinon la
liste des fichiers dans le répertoire courant.
function _MY_COMPLETION_FUNCTION() {
local cur_word=${COMP_WORDS[COMP_CWORD]};
case "${prev_word}" in
PROG_NAME)
words="action1 action2 --option […]"
-o|--option)
words="option1 option2 […]"
;;
*)
words=$(ls -1)
;;
esac
local prev_word=${COMP_WORDS[COMP_CWORD-1]};
COMPREPLY=($(compgen -W "${words}" -- "${cur_word}"))
}
complete -F _MY_COMPLETION_FUNCTION PROG_NAME
Si on ne veut pas que les options déjà présentes soient re-suggérées,
on peut remplacer
COMPREPLY=($(compgen -W "${words}" -- "${cur_word}"))
par
:
opts=();
for i in ${words}; do
for j in "${COMP_WORDS[@]}"; do
if [[ "$i" == "$j" ]]; then
continue 2
fi
done
opts+=("$i")
done
COMPREPLY=($(compgen -W "${opts[*]}" -- "${cur_word}"))
La complétion échappe les deux points
Lors qu’on complète un nom de fichier contenant le caractère deux points « : », Bash échappe les deux points par défaut. Exemple :
$ touch a:b
$ ls a<tab>
$ ls a\:b
Pour empêcher ce comportement :
COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
.
Références :
- https://tiswww.case.edu/php/chet/bash/FAQ, chercher E13 ;
man 1 bash
.