Liens
Début de fichier
|
set -e
set -o pipefail
set -u
wd="$(dirname "$(realpath "$0")")"
|
|
set -e
set +e
set -o pipefail
set -u
|
Debug
Afficher des informations au fil de l'éxecution du script
|
bash -x script.sh
|
Debug a Shell Script Under Linux
Lire les entrées du clavier
Lis le clavier jusqu'à ce que la touche entrée soit pressée.
|
read input
read -r -p 'Entrée : ' input
echo $input
read -r -s -p 'Password : ' password
echo
|
|
echo Titre
PS3='question? '
select choix in \
"Premier choix" \
"Second choix" \
"Quitter"
do
echo Vous avez choisi $choix
case $REPLY in
1) echo choix n°$REPLY;;
2) echo choix n°$REPLY;;
3) exit 0;;
*) echo $REPLY: choix invalide;;
esac
echo
done
|
Arguments passés au script
$*
liste des arguments séparés par des espaces. Attention aux arguments contenant des espaces
"$@"
liste des arguments entourés par des guillemets et séparés par des espaces
$1 ... $9 ${10}
arguments de position, utiliser les accolades à partir de 10
$#
nombre d'arguments
|
for file in "$@" ; do ... ; done
${*// /\\ }
ARGS=("$@")
"${ARGS[@]}"
"${ARGS[0]}"
|
|
OPTS=$(getopt -o vhn -l verbose,help,dry-run -n 'parse-options' -- "$@")
if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
eval set -- "$OPTS"
VERBOSE=false
HELP=false
DRY_RUN=false
while true
do
case "$1" in
-v | --verbose ) VERBOSE=true; shift ;;
-h | --help ) HELP=true; shift ;;
-n | --dry-run ) DRY_RUN=true; shift ;;
-- ) shift; break ;;
* ) break ;;
esac
done
echo HELP=$HELP
echo STACK_SIZE=$STACK_SIZE
if $HELP
then
usage
exit 0
fi
|
test des arguments et usage
|
usage() {
echo "$(basename $0) arg1"
echo ""
echo "arg1: ..."
}
if [[ $# == 0 ]] || [[ -z $1 ]]; then
usage
exit 1
fi
|
shift
Permet de consommer le premier argument et de décaler tous les autres
|
if [[ $1 == '--mon-option' ]]; then
shift
fi
MaFonction $1
|
Redirections
- 0 is stdin, l'entrée standard
- 1 is stdout, la sortie standard
- 2 is stderr, les erreurs
|
commande > fichier
commande 1> fichier
commande 2> fichier
commande 2>&1
commande >file.log 2>&1
commande 2>&1 >file.log
commande &> /dev/null
commande >/dev/null 2>&1
commande 2>&1 | tee fichier
{
echo "1"
echo "2"
} 2>&1 | tee -a log/$(date '+%Y-%m-%d').log
script -q -c 'commande' fichier
|
Variables
|
ma_variable="valeur"
echo $ma_variable
echo $ma_variable1
echo ${ma_variable}1
locale ma_variable="valeur"
readonly my_ro_var='value'
unset ma_variable
set
|
 |
Par défaut, le scope des variables est globale. |
 |
Les noms de variables ne peuvent pas contenir de - |
Variables spéciales
$$ |
PID du shell courant
|
$! |
PID du dernier travail lancé en arrière plan
|
$? |
code retour de la dernière commande
|
Variables d'environnement
$HOME |
chemin du répertoire personnel de l'utilisateur
|
$PATH |
liste des chemins de recherche des commandes exécutables
|
$PPID |
PID du processus père du shell
|
$PWD |
chemin du répertoire courant
|
$RANDOM |
nombre entier aléatoire compris entre 0 et 32767
|
|
printenv
|
Définies dans les fichiers suivants:
- /etc/profile
- /etc/profile.d/*
- $HOME/.zshrc
Stocker le résultat d'une commande
|
currentpath=$(pwd)
cd "$currentpath"
|
String vs entier
Par défaut une variable contient un string. Mais on peut déclarer une variable comme un entier.
|
v=1
v+=1
declare -i v
v=1
v+=1
|
For
|
listeDeChiffres="1 2 3 4 5"
for chiffre in $listeDeChiffres
do
echo chiffre : $chiffre
done
for chiffre in $listeDeChiffres ; do echo chiffre : $chiffre ; done
for lettre in {a..z}
for i in 5 {10..50} 100 110
for i in {10..50..2}
for (( c=1; c<=5; c++ ))
for (( ; ; ))
|
While
|
while [ -z $name ]
do
read -p 'Name : ' name
done
while pgrep firefox >/dev/null
do
read -p 'Fermez Firefox avant de continuer.' askclosefirefoxinput
done
ls -t | while read element
do
[[ -d $element ]] || continue
echo $element
done
while IFS= read -r f; do [ -f "$f" ] && rm -f "$f"; done < list.txt
|
if / else
|
if (expression); then
echo 1
elif ! (expression); then
echo 2
else
echo 3
fi
if [ expression ]; then echo 1; echo 2; else echo 3; fi
|
[[ ]]
|
[[ expression ]] && command
[[ expression ]] || command
|
Booleans
|
var1=false
if $var1
if [ $var1 = true ]
if [[ $var1 = true ]]
|
Strings
|
if [[ $1 == $2 ]]
if [[ $1 != $2 ]]
|
 |
Do not use the ${var} form to call the variable, use $var instead. |
|
if [[ $1 == XXX* ]]
if [[ $1 == *XXX ]]
if [[ $1 == *XXX* ]]
if [[ $1 == *'XXX YYY'* ]]
if [[ $1 =~ [0-9][0-9]\.jpg$ ]]
if [[ $mon_texte =~ http://[a-zA-Z0-9._/]+\.jpg ]]
then
echo "OK: ${BASH_REMATCH}"
else
echo "KO"
fi
if [[ $mon_texte =~ ([0-9]{4})([0-9]{2})([0-9]{2}) ]]; then
echo "${BASH_REMATCH[1]}-${BASH_REMATCH[2]}-${BASH_REMATCH[3]}"
fi
|
 |
Escape the following characters ( ) . |
Entiers
|
if [[ $1 -gt $2 ]]
if [[ $1 -lt $2 ]]
if [[ $1 -ge $2 ]]
if [[ $1 -le $2 ]]
if [[ $1 -eq $2 ]]
if [[ $1 -ne $2 ]]
|
 |
Il est préférable d'utiliser la forme (( ))
|
if (($1>$2))
| |
Opérateurs ET, OU
|
if [[ $1 -gt $2 && $1 -lt 100 || $1 -eq 0 ]]
if [[ $1 -gt $2 && ($1 -lt 100 || $1 -eq 0) ]]
|
Fichiers, dossiers
|
if [[ -e $1 ]]
if [[ -f $1 ]]
if [[ -d $1 ]]
if [[ -L $1 ]]
if [[ -r $1 ]]
if [[ -w $1 ]]
if [[ -x $1 ]]
|
Différences entre [ ] et [[ ]]
- [[ ]] ne fonctionne qu'avec Bash et Korn shell.
- Avec [[ ]], il n'est pas nécessaire d'entourer les variables de quotes
- Avec [[ ]], les parenthèses n'ont pas besoin d'être échappées
La commande test ou [ ]
|
if test -e "$1"
if [ -f "$1" ]
if [ -d "$1" ]
if [ -r "$1" ]
if [ -x "$1" ]
if [ ! ]
if [ -n "$1" ]
if [ -z "$1" ]
if [ e1 -a e2 ]
if [ e1 ] && [ e2 ]
if [ e1 -o e2 ]
if [ e1 ] || [ e2 ]
if [ \(e1 -o e2\) -a e3 ]
if { [ e1 ] || [ e2 ] ; } && [ e3 ]
|
Permet de faire des comparaisons d'entiers
|
if (( $1 > 10 ))
if (( $1 < 20 ))
if (( $1 == 15 ))
if (( $1 != 15 ))
if (( $1 % 100 == 0 ))
echo $(( 1 == 1 ))
|
Mais aussi des opérations sur les entiers
|
echo $(( $1 += 1 ))
echo $(( i += 1 ))
echo $((RANDOM % 10))
|
Nombres commençant par 0
Les nombres commençant par 0 sont traités en octal
|
echo $((08+1))
echo $((10#08+1))
v=08
echo $((10#$v+1))
|
|
while [[ $v = 0* ]]; do v=${v#0}; done
v=${v/*(0)/}
|
String
Exécuter une commande
|
cmd="ls"
eval ${cmd}
$(${cmd})
cmd2=$(${cmd})
echo ${cmd2}
|
Fichiers, dossiers et chemins
|
file="/path/filename.ext"
filename=${file##*/}
filename=basename "$file"
${filename%.*}
${filename##*.}
${file%/*}
readlink -f fichier
|
Concaténation
|
mot1="une"
mot21="bon"
mot22="ne"
echo "$mot1 $mot21$mot22 concaténation"
echo $mot1 $mot21"ne concaténation"
mot1="${mot1} bonne concaténation"
|
Longueur d'un string
|
longueur=${#MonString}
echo "AAA" | wc -c
expr lenght "AAA"
|
Index, position du premier caractère correspondant
|
expr index $string $substring
echo $(expr index "$stringZ" 1c)
|
|
${string:position:length} ou expr substr $string $position $length
expr match "$string" '\($substring\)' ou expr "$string" : '\($substring\)'
expr match "$string" '.*\($substring\)' ou expr "$string" : '.*\($substring\)'
echo ${stringZ:7}
echo ${stringZ:7:3}
echo ${stringZ: -4}
echo ${stringZ:0:-4}
echo $(expr substr $stringZ 4 3)
echo $(expr "$stringZ" : '\(.......\)')
echo $(expr match "$stringZ" '\(.[b-c]*[A-Z]..[0-9]\)')
echo $(expr match "$stringZ" '.*\([A-C][A-C][A-C][a-c]*\)')
|
 |
?, +, {} et | doivent être utilisés avec un backslash : \? \+ \{\} \| |
 |
L'utilisation des parenthèses avec expr match permet de renvoyer un string, sinon un entier est renvoyé égal au nombre de caractères qui correspondent. |
Suppression d'un sous-string
|
${string#substring}
${string##substring}
${string%substring}
${string%%substring}
stringZ=abcABC123ABCabc
echo ${stringZ#a*C}
echo ${stringZ##a*C}
echo ${stringZ%A*c}
echo ${stringZ%%A*c}
echo ${stringZ%a*C}
echo ${stringZ#*C}
echo ${stringZ##*C}
echo ${stringZ%C*}
echo ${stringZ%%C*}
|
Remplacement d'un sous-string
|
${string/substring/replacement}
${string//substring/replacement}
${string/#substring/replacement}
${string/%substring/replacement}
stringZ=abcABC123ABCabc
echo ${stringZ/abc/xyz}
echo ${stringZ//abc/xyz}
echo ${stringZ/#abc/XYZ}
echo ${stringZ/%abc/XYZ}
echo ${stringZ//\\//}
|
Permet de construire une liste d'argument.
|
echo 1 2 3 4 | xargs
echo 1 2 3 4 | xargs cmd
echo 1 2 3 4 | xargs -n 1 cmd
find . -iname "*.mp3" -print0 | xargs -0 -I mp3file mplayer mp3file
ls -t "${MyPath}" | tail -n +3 | xargs -0 rm -f --
|
 |
-0 Gère les chemins avec des espaces. |
Tableaux / Arrays
Par défaut toutes les valeurs du tableau sont vide. Il n'est pas nécessaire de l'initialiser. Sa taille n'est pas définie.
|
monTableau=()
monTableau=(valeur0 valeur1 valeur2)
monTableau=([0]=valeur0 [10]=valeur10)
echo ${monTableau[10]}
monTableau[5]=valeur5
monTableau+=('valeurX')
echo ${#monTableau[@]}
if [[ " ${monTableau[@]} " =~ " ${value} " ]]; then
fi
for element in "${monTableau[@]}"
do
echo $element
continue
done
printf "%s\n" "${monTableau[@]}"
IFS=§
rm -f ${monTableau[@]}
IFS=$'\n' read -r -d '' -a my_array \
< <(find '/folder' -maxdepth 1 -type d -printf "%f\n" && printf '\0')
|
Associative arrays / Hash tables / Dictionnaires
|
declare -A map
map[key1]="Value 1"
echo ${map[key1]}
declare -A map=( [key1]="Value 1" )
for key in "${!map[@]}"; do
echo "$key - ${map[$key]}"
done
|
|
set -e
trap 'echo 333' EXIT
echo 111
'commande inconnue'
echo 222
trap - EXIT
echo 444
|
Signaux
EXIT |
appel d'«exit» ou sortie du script suite avec l'option «set -e» suite à une erreur
|
INT |
Ctrl-C from the keyboard
|
TERM |
kill du processus
|
Fonctions
|
Fonction() {
$0
$1
$@
$#
local variable_locale="pouet!"
echo $FUNCNAME // nom de la fonction: Fonction
return 0
}
Methode arg1 arg2
echo $?
var=$(Methode arg1 arg2)
|
 |
Par défaut dans bash les variables sont globales.
Les variables sont donc accessibles dans et à l'extérieur des fonctions. |
Lire et écrire dans un fichier
|
echo 1 > fichier.txt
echo 1 >> fichier.txt
ma_variable=$(cat fichier.txt)
|
extglob option
Permet d'étendre les pattern matching operators:
Operators
|
Explanations
|
?(pattern-list) |
Matches zero or one occurrence of the given patterns
|
*(pattern-list) |
Matches zero or more occurrences of the given patterns
|
+(pattern-list) |
Matches one or more occurrences of the given patterns
|
@(pattern-list) |
Matches one of the given patterns
|
!(pattern-list) |
Matches anything except one of the given patterns
|
|
shopt extglob
shopt -s extglob
shopt -u extglob
ls !(*-small.jpg)
|
|
. /chemin/vers/un/autre/script.sh
source /chemin/vers/un/autre/script.sh
. "$(dirname $0)/un_autre_script.sh"
/chemin/vers/un/autre/script.sh
bash /chemin/vers/un/autre/script.sh
|
Hasher un string
|
echo -n "mon string" | md5sum
echo -n "mon string" | sha512sum
|
Free Password Hash Cracker
Astuces
Quitter le script
|
exit 0
|
 |
0 : succès
1 ou plus : erreur |
Enchaînement de commandes et test code de retour
Si la commande a fonctionnée elle renvoie 0 et le code après les && est éxecuté,
dans le cas contraire la commande n'a pas fonctionné correctement et a renvoyé 1, le code après les || est alors exécuté.
|
commande && echo ok || echo ko
commande
if [ $? -ne 0 ]; then
echo ko
fi
|
Chemin absolu du script et de son dossier
|
$(realpath "$0")
$(dirname "$(realpath "$0")")
|
True / False
|
true; echo $?
false; echo $?
echo $((1 == 1))
ok=true
if [[ ${ok} == true ]]
ok=0
if ((ok))
ok=1
if ((ok))
|
Max
|
max() {
if (( $# != 2 )); then
return 1
fi
if (( $1 == $2 )); then
echo $1
else
if (( $1 > $2 )); then
echo $1
else
echo $2
fi
fi
return 0
}
m=$(max 10 5)
m=$(max 10)
|
Forcer la sortie en anglais
|
LC_ALL=C macommande
|
Relancer le script avec un autre utilisateur
|
if [[ $UID -ne 1000 ]]; then
su user1000 -c "bash $0"
exit $?
fi
|
Relancer le script avec script pour créer un fichier de log
|
if [ -z ${restart+x} ]; then
export restart=true
script_path=$(realpath "$0")
dir_path=$(dirname ${script_path})
file_name=$(basename "$0")
script -q -c "${script_path}" "${dir_path}/${file_name%.*}.log" && exit
fi
|
Test si l'utilisateur est root
|
if [[ $UID -ne 0 ]]; then
echo 'Only the root user can run this script.'
exit 1
fi
|
Lancer une commande avec root sans demande de mot de passe
|
echo 'mot de passe' | su -c 'ma commande'
|
Mise en forme la sortie en colonnes
|
ls -1 | column
ls -1 | pr -3 -t
ls -1 | pr -3 -t -s'|' | column -t -s'|'
|
Alias console
~/.bashrc
|
alias ll='ls -alF'
alias ds='df -t ext4 -h | grep home | awk '"'"'{ print $4 }'"'"''
unalias ll
|
Les alias peuvent être écrit dans un fichier séparé : .bash_aliases
~/.bashrc
|
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
|
Fonctions console
~/.bashrc
|
function fn() { sudo find / -name ''$1'' ;}
function fit()
{
find . -type f -exec awk -v vawk="$1" '$0 ~ vawk {c++} c>0 {print ARGV[1] ; exit 0 } END { if (! c) {exit 1}}' \{\} \;
}
function xxx()
{
echo $1
}
xxx *.pdf
xxx "*.pdf"
xxx \*.pdf
|
~/.bashrc
|
PS1="\[\e[1;34m\]\w\$(if [[ \$(expr length \"\w\") -gt 50 ]]; then echo \"\n\r\"; else echo \" \"; fi)➭ \[\e[0m\] "
|
Codes
- \u : login de l'utilisateur
- \h : le nom de la machine
- \w : le répertoire courant
- \$ : # pour root, sinon $
Couleurs
|
Color_Off='\e[0m'
Black='\e[0;30m'
Red='\e[0;31m'
Green='\e[0;32m'
Yellow='\e[0;33m'
Blue='\e[0;34m'
Purple='\e[0;35m'
Cyan='\e[0;36m'
White='\e[0;37m'
BBlack='\e[1;30m'
BRed='\e[1;31m'
BGreen='\e[1;32m'
BYellow='\e[1;33m'
BBlue='\e[1;34m'
BPurple='\e[1;35m'
BCyan='\e[1;36m'
BWhite='\e[1;37m'
UBlack='\e[4;30m'
URed='\e[4;31m'
UGreen='\e[4;32m'
UYellow='\e[4;33m'
UBlue='\e[4;34m'
UPurple='\e[4;35m'
UCyan='\e[4;36m'
UWhite='\e[4;37m'
On_Black='\e[40m'
On_Red='\e[41m'
On_Green='\e[42m'
On_Yellow='\e[43m'
On_Blue='\e[44m'
On_Purple='\e[45m'
On_Cyan='\e[46m'
On_White='\e[47m'
IBlack='\e[0;90m'
IRed='\e[0;91m'
IGreen='\e[0;92m'
IYellow='\e[0;93m'
IBlue='\e[0;94m'
IPurple='\e[0;95m'
ICyan='\e[0;96m'
IWhite='\e[0;97m'
BIBlack='\e[1;90m'
BIRed='\e[1;91m'
BIGreen='\e[1;92m'
BIYellow='\e[1;93m'
BIBlue='\e[1;94m'
BIPurple='\e[1;95m'
BICyan='\e[1;96m'
BIWhite='\e[1;97m'
On_IBlack='\e[0;100m'
On_IRed='\e[0;101m'
On_IGreen='\e[0;102m'
On_IYellow='\e[0;103m'
On_IBlue='\e[0;104m'
On_IPurple='\e[0;105m'
On_ICyan='\e[0;106m'
On_IWhite='\e[0;107m'
|
Exemples
Lister les dossiers par ordre décroissant de création
|
ls -t | while read element
do
[[ -d $element ]] || continue
echo $element
done
|
Récupérer le nom du fichier / dossier le plus récent
|
set +u
unset -v latest
for element in *; do
[[ $element -nt $latest ]] && latest=$element
done
set -u
echo $latest
|
Renommer tous les fichiers ayant pour extension "TXT" en "txt"
Par exemple "file.TXT" devient "file1.txt" :
|
SUFF=TXT
suff=txt
for i in *.$SUFF
do
mv -f $i ${i%.$SUFF}.$suff
done
|
 |
Si aucun fichier *.TXT n'existe, le script a un comportement bizarre. |
Suppression des dossiers .svn
dans le répertoire courant et dans tous les sous-répertoires :
|
DelDotSvnDirectory()
{
for subDirectory in $(ls -l | grep ^d |
awk '{ for (i=9; i<NF; i++) printf $i"°" ; print $NF }')
do
cd "${subDirectory//°/ }"
DelDotSvnDirectory
done
if [ -d ".svn" ]; then
rm -rf ./.svn
fi
cd ..
}
DelDotSvnDirectory
|