Sur les systèmes Unix, les blocs de commande ne sont rien de plus qu'un chaînage de plusieurs instructions qui s'exécuteront de manière séquentielle.
Mais avant d'entrer dans le vif du sujet il me semble important de bien comprendre le mécanisme des flux d'entrée/sortie et de le garder dans un coin de sa tête.
Un shell Linux utilise trois flux d'entrée/sortie.
Tout ce qui est entré au clavier est envoyé à l'entrée standard (stdin), ensuite le shell retourne un résultat sois sur la sortie standard (stdout) en cas de succès, sois sur l'erreur standard (stderr) en cas d'échec.
Identifiant | nom (abréviation) | usage |
---|---|---|
0 | entrée standard (stdin) | clavier |
1 | sortie standard (stdout) | console |
2 | erreur standard (stderr) | console |
Toute commande passée au système retourne un état, 0 (zéro) si tout s'est déroulé normalement ou une autre valeur comprise entre 1 et 255 en cas d'échec.
Le point virgule autorise l'échec d'une ou plusieurs instruction, ces dernières sont donc exécutées indépendamment les unes des autres quoi qu'il arrive, quel que soit l'état retourné.
$ cd bin/ ; touch fichier.txt
Si dans l'exemple ci-dessus le répertoire "bin" n'existe pas, la première instruction retournera une erreur et le "fichier.txt" sera créé dans le répertoire courant. Inversement, si le répertoire "bin" existe mais ne dispose pas des droits en écriture, seule la première instruction sera exécutée et le "fichier.txt" ne sera pas créé.
Contrairement au point virgule, la double esperluette && interrompt l'exécution d'un bloc de commande dès qu'une erreur intervient (état autre que 0).
$ cd bin/ && touch fichier.txt
Ici, si le répertoire "bin" n'existe pas une erreur est soulevée et tout ce qui suit la commande "cd" ne sera pas exécuté.
La double barre verticale peut être assimilée à un ou conditionnel (ou-bien), si la première suite d'instruction échoue, alors exécuter ce qui suit ||.
Les deux blocs de commandes suivants auront le même effet:
$ cd bin/ && touch fichier.txt ||mkdir bin && cd bin/ && touch fichier.txt
$ cd bin/ ||mkdir bin && cd bin/ ; touch toto.txt
Notez que je ne met pas d'espace entre || et mkdir sans quoi j'ai une erreur:
bash: mkdir : commande introuvable
.
J'ignore si c'est du à mon système mais tout ce qui suit immédiatement || (même un espace) est interprété.
L'expression $() permet de récupérer la sortie d'une commande pour l'injecter comme argument dans une autre.
Par exemple pour créer dynamiquement un répertoire portant la date du jour:
$ mkdir $(date "+%d-%m-%Y")
$ ls | less
Il est possible de récupérer la valeur numérique d'un code de retour grâce à la variable $? .
$ autodestruction
autodestruction : commande introuvable
$ echo $?
127