Dans sa forme simple une commande est écrite avec un premier mot qui
définit la commande et les mots suivants sont des paramètres fournis à
la commande; elle peut être complétée par des redirections d'entrée ou
de sortie.
envoiFs toto@alamer.org $REP/*.C
g++ horloge.C 2> erreurs
On peut aussi modifier des valeurs de variables d'environnement,
avant d'appeler la commande, qui tiendra compte du nouvel environnement.
Toutefois cette modification ne concerne pas l'environnement des
commandes suivantes.
MAP=OUI ADR=toto@alamer.org envoiFs $ADR $REP/*.C
On peut ainsi dégager la syntaxe suivante, pour une commande simple:
affectations nom   liste de paramètres
redirections
Les séparateurs || & && ; ;; ( ) | "r.chariot" isolent des commandes simples.
Le caractère $ introduit un remplacement de paramètres, une substitution de commande ou un calcul arithmétique, sauf s'il est précédé de \.
Comment se fait l'exécution d'une commande?
Le premier mot qui suit des affectations désigne la commande
exécuté; il est analysé:
echo file{1,2}
file1 file2
On voit que ~abc est rempacé par le répertoire d'accueil de
l'utilisateur "abc"; ~+ est remplacé par le répertoire courant.
echo ~astier
/dptinfo/users/astier
echo ~+
/dptinfo/users/astier/sys/itp
${12}
{} est à utiliser avec plus de 9 paramètres
echo $HOME
/dptinfo/users/astier
${#HOME}
21 (nombre de caractères)
Il y a équivalence entre $( ... ) et ` ... `
$(ls e*)
edcomp.C edcomp.o
`ls e*`
edcomp.C edcomp.o
$((3+5*8))
43
echo $((`ls | wc-l` - 2))
17 (nombre de fichiers - 2)
Ajoutons que, dans un script, l'expression "$*" est développée en
un mot, alors que "$@" est développée en autant de mots
qu'il y a de paramètres.
x="p_q uv"
"a b" $x
3 mots, qui sont 'a b' 'p_q' 'uv'
"a b" "$x"
2 mots, qui sont 'a b' 'p_q uv'
'a b' '$x'
2 mots, qui sont 'a b' '$x'
e*
ess3.C ess5.C ess6.cpp
ess[2-5]*
ess3.C ess5.C
"e*"
e*
Ce paragraphe concerne l'éciture de scripts, c'est-à-dire l'enchaînement de commandes écrites dans un fichier. Il existe un véritable langage, avec des variables et les structures de contrôle généralement recontrées dans les langages de programmation.
if echo $PATH | /java130/bin >/dev/null then echo /java130/bin déjà présent dans le chemin else PATH=$PATH:/usr/java130/bin echo variable modifiée, \$PATH=$PATH fiLa même modification conditionnelle est affectuée ci-dessous, sans affichage; remarquez l'utilisation de ":", qui est l'instruction vide.
if echo $PATH | grep /java130/bin >/dev/null then : else PATH=$PATH:/usr/java130/bin fiIntroduisons maintenant une négation, et nous n'avons plus que le bloc "then".
if ! echo $PATH | grep /java130/bin >/dev/null; then PATH=$PATH:/usr/java130/bin fiVoici enfin un exemple utilisant "elif" pour traiter une alternative multiple. La séquence ci-dessous vérifie que l'appel du script se fait avec un seul paramètre, pouvant être "-h" ou un nom ayant l'extension .cpp.
if [ $# -ne 1 ]; then echo "$0 a un et un seul paramètre" exit 1 elif [ $1 = -h ]; then echo "$0 étudie un fichier source d'extension cpp" exit 2 elif [ $(1%\.cpp) = $1 ]; then echo "Il faut que l'extension soit cpp" exit 3 else : # déroulement normal fi
case $1 in *.h) echo "$1 est un fichier d'entête" *.C | *.cc | *.cpp) echo $1 est un fichier source C++ ;; *.[Jj]ava) echo $1 est un fichier java echo " "il faut compiler avec javac;; *) echo Je ne sais pas esac
La séquence suivante affiche les fichiers du répertoire courant ayant des extensions particulières; cet affichage peut être obtenu par une seule instruction, mais ici nous présentons un exemple d'instruction répétitive.
for i in .h .C .cpp .cc do echo "Fichiers d'extension $i": ls $i 2>/dev/null done
La séquence suivante affiche les fichiers du répertoire courant ayant
des extensions particulières, qui sont passées en paramètre au script.
Cela montre que si aucune suite n'est mentionnée dans l'instruction
for, alors la liste des paramètres est utilisée.
for ext do echo "Fichiers d'extension $ext": ls $i 2>/dev/null done
while read ligne do echo $ligne done < unFic
La partie "condition" correspond à une instruction dont le code retour représente la valeur booléenne; le corps est la suite d'instructions encadrée par les deux mots "do" et "done".
Voici le texte de deux fonctions, qui doit précèder leur utilisation; la première effectue un affichage et la deuxième effectue une lecture
# Affiche les variables exportées dont le début du nom est fourni function aff { echo chez $USER, "variable(s) trouvée(s)" env | grep ^$1 } # Affiche un message, et lit un mot # Renvoie un code retour non nul (FAUX) si le mot est "." lecture() { local FIN MSG FIN=. MSG="Variable commençant par (arrêt sur $FIN) : " echo -n $MSG read debut [ "$debut" != $FIN ] }
L'utilisation de ces fonctions, consiste à demander
un début de mot et afficher les variables "exportables" qui commencent
par les lettres lues. Cela permet de mieux connaître des variables de
son environnement de travail sans avoir à lire tout l'environnement
de l'interprète de commandes.
Les appels de fonction sont détectés uniquement par la présence du
nom de la fonction.
while lecture do aff $debut done