Bash : Bourne-again shell
- Successeur libre au Bourne Shell historique
- Quelques différences vis à vis de 'sh'
- Interpréteur de commande du projet GNU
Hello World
echo Hello World !
---
echo -n Hello
echo World !
---
MSG="Hello World"
echo $MSG
---
MSG1="Hello"
MSG2="World !"
echo $MSG1 $MSG2
Shebang
Spécifier quel interpréteur utiliser
#!/bin/bash
et, pour rendre le fichier exécutable
chmod a+x mon_script.sh
l'exécution
./mon_script.sh
Un script de backup
#!/bin/bash
tar -zcvf ~/backup-$(date +'%d-%m-%Y').tar.gz /un_dossier/
- -zcvf :
- z : compression gzip
- c : 'concatenation' du dossier/fichiers
- v : verbose, informations pendant les opérations
- f : dernier 'switch' qui indique le fichier de sortie
- ~ : correspond au dossier personnel
- $(expression) : évalue l'expression
Nous aurons alors un fichier back-11-11-2006.tar.gz dans notre dossier personnel
Redirection1
ps aux | grep bash > opened_shell.txt
- ps aux : affiche toute la liste des processus
- | : 'pipe', la sortie de la commande de gauche devient l'entrée de la commande de droite
- > : redirige la sortie standard vers le fichier opened_shell.txt
Redirection 2
Il existe 3 descripteurs d'entrée sortie sous *NIX
- 0 : stdin - entrée standard (le clavier, entrée par un 'pipe' |)
- 1 : stdout - sortie standard (l'affichage à l'écran)
- 2 : stderr - sortie d'erreur (les erreurs, logs, ..., affichées à l'écran)
# on ne veut pas de stderr
./programme 2>/dev/null
#stdout et stderr affichées, et dans logs.txt
#tee redirige dans un fichier
#et affiche sur la sortie standard
./programme 2>&1 | tee logs.txt
Pipe
grep $USER /etc/passwd | sed 's/:/, /g'
- $USER : une variable d'environnement, 'vous'
- sed : remplace ':' par ', '
- s/patt/patt2/ : remplacement
- s/patt/patt2/g : pour chaque occurence d'une ligne
D'autres variables d'environnement : $HOME, $PWD, $PATH
La commande 'env' affiche toutes les variables d'environnement
Blocs conditionnels
if [ -f un_fichier ]; then
echo un_fichier existe;
fi
if [ 3 -lt $VAR ]; then
echo $VAR plus grand que 3;
else
echo $VAR plus petit que 3;
fi
- Pour les nombres : -lt, -gt, -le, -ge, -eq, -ne
- Pour le 'texte' : =, !=
for i in foo bar baz; do
echo $i
done
for i in `seq 1 10`; do
echo $i
done
- `seq 1 10` : évalue la commande (comme $(exp) )
- la série des valeurs est injectée sur $i
- fonctionne aussi avec un 'for i in *.txt' par exemple
Boucle
CPT=0
while [ $CPT -lt 10 ]; do
echo $CPT
let CPT+=1
done
Trivial
EX1 : Nombre de connectés
ps h -aef|awk '{print $1}' | sort | \
uniq -c | awk '{print $2" has "$1" process"}'
EX2 : Utilisateurs d'un groupe
echo -n "GROUP: "
read GROUP
echo "`ps h -f -G $GROUP | awk '{print $1}' | \
sort -u | wc -l` user(s) of grp $GROUP connected"
EX3 : Ajouter "foobar" au .bash_login des users bash
for i in `grep '/bin/bash$' /etc/passwd | \
cut -d: -f6`; do echo "echo foobar" >> "$i/.bash_login";
done
EX4 : Trouver et lister les fichiers de plus de 20k
find / -size +20k -exec ls -l {} \;
EX5 : Trouver les dossiers mails d'anciens utilisateurs
for i in /var/mail/*;
do grep -q `basename $i` /etc/passwd;
if [ $? -eq 1 ];
then
echo `basename $i`;
fi;
done