Shell
Un interpreteur de commandes ou « shell » permet d’acceder au systeme de maniere sécurisée, sans avoir a écrire de programmes et en limitant le risque de le rendre inutilisable.
Il se présente sous la forme d’une invite de commandes qui interpret puis execute les commandes entrées par l’utilisateur.
Cette vidéo explique entre autres la place du “shell” dans un systeme UNIX (vers 5:00), et differents éléments de la philosophie d’UNIX : programmes de petite taille s’imbriquant les uns avec les autres, abstraction des differents composants materiels qui permet de lire et ecrire n’importe quoi depuis et vers n’importe quoi avec un seul programme.
Un programme UNIX est préférablement une brique d’une ligne de commande invoquée par un « shell » : avant d’écrire des programmes en ligne de commande il convient de maitriser les bases du shell.
SH, Dash, KSH, CSH, BASH, ZSH
Il existe de nombreux shells qui ajoutent des fonctionnalités à ceux qui existaient avant eux, ou bien incompatibles totalement avec les shells existants déjà.
Une norme POSIX garantit certainent fonctionnalités et un socle commun pour écrire des scripts shells portables.
SH est le shell “originel” et bash, ksh, dash en sont dérivés. Zsh est lui dérivé de Ksh.
CSH est un shell inspiré du langage C plutot que de la syntaxe de SH. Il a été populaire mais décrié aujourd’hui : csh programming considered harmful https://web.mit.edu/ghudson/info/csh.whynot 🌍⤴ .
Nous utiliserons le shell : dash, qui est un
shell léger
(man dash | wc -l
contre man bash | wc -l en donne
une idée).
Ce shell est livré par défaut avec la plupart
des distributions Linux (WSL y compris) et sur MacOS.
Ce qui est valide avec dash le sera aussi sur
bash ou zsc alors que la réciproque n’est pas vrai.
Taper dash dans une invite de commandes ouvre une session, quit ferme la session. man dash affiche un manuel d’usage du shell sans doute plus complet que ce chapitre.
rc est également un shell léger avec un cours
succint et bien expliqué (en anglais) :
https://doc.cat-v.org/plan_9/4th_edition/papers/rc
🌍⤴
Commandes de base
Voilà quelques exemples de commandes que peut comprendre un shell (depuis le manuel de rc) :
date
cat /lib/news/build
who >user.names
who >>user.names
wc <file
echo [a-f]*.c
who | wc
who; date
vc *.c &
mk && v.out /*/bin/fb/*
rm -r junk || echo rm failed!
Affiche la date, affiche le contenu de /lib/news/build,
écrit les utisateurs connectés dans le fichier
user.names, rajoute à la fin une deuxieme fois les
utilisateurs connectés, compte les mots du fichier file,
affiche tous les fichiers dans le répertoire courant
qui commencent pas une lettre entre “a” et “f” et se
terminent par “.c”, compte le nombre d’utilisateurs
connectés, exécute successivement who et date
en une seule commande, exécute la commande vc puis
la relègue en tache de fond non bloquante, enchaine
les commandes mk et v.out uniquement si la commande
mk a réussi, exécute rm, puis echo si la commande
rm a échoué.
Creer des fichiers et traitement en masse
On va commencer par creer 10 fichiers
nommés 1toto.c, 2toto.c, etc.
for i in 1 2 3 4 5 6 7 8 9 10; do
touch ${i}toto.c
done
ou encore
for i in $(seq 1 10); do
touch "$i"toto.c
done
Si on écrivait simplmenent $itoto.c, l’interpreteur
recherche la variable “itoto.c” et retourne
une chaine vide si la variable n’existe pas,
pour isoler la variable du reste de la chaine il faut écrire
soit "$i"toto.c, soit $i"toto", ou encore $i""toto
ou bien $i''toto, ou bien ${i}toto.
Avec bash et zsh, une manière plus concise
de procéder est touch {1,2,3,4,5,6,7,8,9,10}toto.c,
ou encore touch {1..10}toto.c.
On a vu que l’interpreteur concatene les chaines
de caractere et traite ' et " comme délimiteur.
echo "to""to" affiche toto.
Si on veut utiliser ces caractères en tant que tels,
il faut les entourer avec les
autres guillemets : echo '"'L"'"histoire sans fin'"'.txt
affiche "L'histoire sans fin".txt.
Les motifs de substitution
Les caractères [, ? et * dans un argument
ont une signification
particuliere. dash autorise touch to*to.c, mais pas bash, il vaut mieux en général
entourer ces caractères entre guillements :
touch to'*'to.c.
Pour rechercher des fichiers contenant ces caractères, les entourer de guillements echo *'*'*.
$ echo ??toto*
10toto.c
$ echo ?to*
1toto.c 2toto.c 3toto.c 4toto.c 5toto.c 6toto.c 7toto.c 8toto.c 9toto.c
$ echo [1-5]
[1-5]
$ echo [12345]t*
1toto.c 2toto.c 3toto.c 4toto.c 5toto.c
$ echo [1-5]*
10toto.c 1toto.c 2toto.c 3toto.c 4toto.c 5toto.c
$ echo [1-5]t*
1toto.c 2toto.c 3toto.c 4toto.c 5toto.c
$ echo [1-36-8]t*
1toto.c 2toto.c 3toto.c 6toto.c 7toto.c 8toto.c
$ echo [!1-2]t*
3toto.c 4toto.c 5toto.c 6toto.c 7toto.c 8toto.c 9toto.c
$ echo [!1-36-8]t*
4toto.c 5toto.c 9toto.c
? se substitue à un seul et unique caractères, *
se substitue à n’importe quelle succession de caractères,
[] permet de spécifier une classe de caractères,
un tiret - specifie une plage de caractères.
Les caracteres /, . et .. ne sont pas considérés
dans les substitutions, la recherche de fichiers
ne se fait donc pas ni dans les répertoires
descendants, ni parents, ni recursivement courant.
Lors