Le shebang
#!
Permet de signifier à l’OS que le fichier est un script exécutable. La commande file identifie le contenu d’un fichier grâce au shebang, et non par son extension ou les lignes de codes qui le constituent.
Il est possible qu’il s’agisse de la contraction de sharp (#) et bang (!), de celle de hash (#) et bang (!), ou tout simplement de shell et bang (!).
Il peut aussi être appelé shabang, sha-bang, she-bang ou encore hash-bang.
Sur la même ligne se trouve le chemin absolu vers l’interpréteur qui devra être utilisé.
Pour le Bourne Shell (« le shell ») :
#!/bin/sh
Pour le Bourne Again Shell :
#!/bin/bash
L’exécution d’un script
Si le script ne possède pas de shebang en en-tête (ce qui ne devrait jamais être le cas) ou qu’il ne possède pas les droits d’exécution (u+x) :
sh filename.sh
ou
bash filename.sh
On spécifie ainsi l’interpréteur à utiliser pour exécuter le script.
Toutefois, un script possède systématiquement l’en-tête cité précédemment, et la procédure pour l’exécuter est la suivante :
chmod u+x filename.sh
./filename.sh ../adminsys/filename.sh /home/adminsys/filename.sh
On rend le script exécutable pour le propriétaire puis on l’exécute à partir du répertoire courant ou en spécifiant un chemin relatif/absolu.
Le script, s’il est dans le répertoire courant s’exécute en le préfixant de ./ car sans cela la commande serait recherchée dans le PATH et ne serait pas reconnue, à moins qu’une commande système porte le même nom, ce qui est une très mauvaise idée pour un nom de script, ou que le répertoire courant soit inclus dans le PATH, ce qui est également une très mauvaise décision en termes de sécurité.
# filename.sh
bash: filename.sh : commande introuvable
Retourne une erreur car filename.sh est recherché dans les répertoires constituant la variable d’environnement PATH.
# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# .filename.sh
bash: .filename.sh : commande introuvable
La même erreur est retournée si on le préfixe d’un point pour la même raison, une commande .filename.sh (script caché cette fois-ci) est recherchée dans le PATH mais n’est pas trouvée.
La bonne manière de procéder est donc la suivante :
./filename.sh
car filename.sh et ./filename.sh sont équivalents, à la différence près que la première commande est recherchée dans le PATH alors que la seconde est recherchée dans le répertoire courant.
# ls -l filename.sh -rwxr--r-- 1 root root 15 nov. 22 10:49 filename.sh # ls -l ./filename.sh -rwxr--r-- 1 root root 15 nov. 22 10:49 ./filename.sh
# ls -l ./* -rw-r--r-- 1 root root 0 nov. 22 11:05 ./file1.txt -rw-r--r-- 1 root root 0 nov. 22 11:05 ./file2.txt -rw-r--r-- 1 root root 0 nov. 22 11:05 ./file3.txt -rw-r--r-- 1 root root 0 nov. 22 11:05 ./filename.sh # ls -l * -rw-r--r-- 1 root root 0 nov. 22 11:05 file1.txt -rw-r--r-- 1 root root 0 nov. 22 11:05 file2.txt -rw-r--r-- 1 root root 0 nov. 22 11:05 file3.txt -rw-r--r-- 1 root root 0 nov. 22 11:05 filename.sh
Les redirections
Redirection de stdout et stderr vers un même fichier de sortie
Solution répandue mais non portable :
En début de fichier :
command &> file1.txt
Ou, en mode append :
command &>> file1.txt
Solution portable, à privilégier :
En début de fichier :
command > file1.txt 2>&1
Ou, en mode append :
command >> file1.txt 2>&1
Redirige stderr (descripteur 2) au même endroit que stdout (descripteur 1), ici file1.txt.
Les expressions régulières simples et étendues
regexp simple |
[…] | ensemble | |
[^…] | ensemble exclu | ||
[x-y] | intervalle | ||
. | n’importe quel caractère | ||
répétition | * | zéro ou plus | |
+ | un ou plus | ||
? | zéro ou un | ||
{n} | n fois | ||
{n,m} | de n à m fois | ||
regexp étendue |
| | ou logique | |
(…) | sous-section | ||
ligne | ^ | début | |
$ | fin |