Stage de rentrée I1

Bash II


Substitutions de la ligne de commande

Sous bash, comme sous tous les interpréteurs de commandes, entre le moment où une commande est validée par l'utilisateur (en appuyant sur la touche <ENTRÉE>) et où elle est exécutée, se produit une phase de traitement pendant laquelle ont lieu des substitutions de texte.

Ces plases sont, dans l'ordre :

Nous n'allons pas voir ici à quoi toutes correspondent. Nous en verrons les principales. Pour les autres, vous pourrez toujours faire info emacs, et voir l'item « Shell expansions ».

Expansion des accolades

L'expansion des accolades est un mécanisme purement syntaxique (qui ne dépend pas de l'existence, dans le système, d'objets portant les noms manipulés). Elle consiste à remplacer une séquence de caractères : avant{a,b,c}après par les séquences : avantaaprès, avantbaprès et avantcaprès, séparées par des espaces.

Exemple : mkdir /net/i1/login/projet/{src/{module1,module2},lib,bin}.

On peut le tester en faisant un echo de la chaîne ci-dessus.

La substitution est faite même si les noms de fichiers ci-dessus n'existent pas encore, à la différence d'avec la substitution des noms de fichiers que l'on verra après. C'est même l'avantage pour les créer, comme dans l'exemple ci-dessus.

Expansion du tilde

Déjà vue. Remplace la chaîne ~login par le répertoir d'accueil de l'utilisateur login, soit, pour un I1, le répertoire : /net/i1/login.

Expansion des variables et des paramètres

Permet le remplacement des noms de variables d'environnement par leur valeur. Les noms de variables à substituer peuvent être de la forme $NOM ou bien ${NOM}. Par exemple : echo $PATH, ou bien echo ${PATH}.

La deuxième forme permet d'insérer des options supplémentaires, comme par exemple de mettre une chaîne par défaut si le nom de variable n'est pas connu de l'interpréteur. Exemple :


% echo ${BROL:-Je ne le connais pas}
Je ne le connais pas
% export BROL="Monsieur Brol"
% echo ${BROL:-Je ne le connais pas}
Monsieur Brol

Pour plus d'informations sur toutes les possibilités et noms de variables spéciales, voir info bash.

Substitutions de commandes

Les suites de texte entre apostrophes inverses sont remplacées par le résultat de l'exécution de la commande correspondante dans un sous-shell.

Par exemple :


% export VAR=`date`
% echo $VAR

Coupure des mots

Toute séquence de blancs (espaces, tabulations, ou retours de ligne) sert de délimiteur entre chaque mot (paramètre, option) de la commande.

Pour garder des espaces dans un mot, on peut utiliser le caractère d'échappement "\", comme dans mkdir brol\ et\ trol, qui permet de manipuler des noms de fichiers avec des espaces. Voir que l'interpréteur met lui-même des backslash lors de la complétion de nom de commande (touche <TAB>).

On peut aussi mettre une chaîne contenant des espaces entre simples quotes (pas d'interprétation du tout de son contenu) ou entre double quotes (interprétation de son contenu). Exemple :


% echo "$BROL et trol"
Monsieur Brol et trol
% echo '$BROL et trol'
$BROL et trol

Expansion des noms de fichiers

Chacun des mots de la commande est analysés à la recherche des caractères '*', '?' et '['. S'ils sont trouvés, alors le mot est considéré comme un motif de noms de fichier, et il est remplacé par la suite triée alphabétiquement des noms de fichiers correspondant au motif.

Le sens des caractères de motif est le suivant :

*
Équivaut à n'importe quelle chaîne, même la chaîne vide ;
?
Équivaut à n'importe quel unique caractère ;
[...]
Équivaut à n'importe quel caractère spécifié dans le domaine désigné entre crochets. Entre crochets :

Exemple : ls -l /usr/lib/lib[a-jt-z]??e* .

Petits trucs avec les noms de fichiers

On a vu comment traiter le cas embêtant des espaces dans les noms de fichiers grâce au backslash ou à la mise entre apostrophes.

Un autre problème est d'avoir un nom de fichier commenant par un tiret. Si on spécifie le nom de fichier tel quel, il est pris pour une option, et les commandes diront qu'elles ne connaissent pas cette option. Par exemple : touch -brol .

Une solution possible consiste à préfixer le nom de fichier par un nom de chemin, pour que le premier caractère ne soit plus un tiret, comme par exemple dans touch ./-brol .

Sinon, de nombreuses commandes de l'environnement GNU ont comme option particulière le double tiret, qui spécifie que tout ce qui se trouve après n'est plus une option mais un nom de fichier. On peut donc, sous un environnement GNU, taper : touch -- -brol .

Redirections

Tous les processus UNIX possèdent trois flots de données stnadards :

Unix permet, grâce à sa conception modulaire, de faire de la « plomberie » sur les flots et de rebrancher les flots d'une commande vers ou à partir de fichiers, ou bien de chaîner le flot de sortie d'une commande vers le flot d'entrée d'une autre. Ce mécanisme s'appelle la redirection.

Sous bash, l'utilisateur dispose de plusieurs mots clés pour spécifier les redirections associées à sa ou ses commandes :

< nom de fichier
Redirige l'entrée standard de la commande à partir du nom de fichier donné ;
> nom de fichier
Redirige la sortie standard de la commande vers le fichier de nom donné. S'il existe déjà, son contenu est écrasé ;
>> nom de fichier
Redirige la sortie standard de la commande vers le fichier de nom donné. S'il existe déjà, le résultat produit par la commande est ajouté au contenu du fichier ;
&> nom de fichier
Redirige la sortie standard et la sortie d'erreur de la commande vers le fichier de nom donné. S'il existe déjà, son contenu est écrasé ;
commande1 | commande2
Crée un tube de communication (pipe) entre la sortie standard de la commande1 et l'entrée standard de la commande2.
num1 >& num2
Redirige le flot de numéro num1 vers la destination du flot de numéro num2. L'usage le plus courant est de rediriger la sortie d'erreur vers la sortie standard, avant de faire un pipe, par exemple : 2>&1.
Attention : l'ordre des redirections est important. Par exemple, > fichier 2>&1 renvoie les deux flots de sortie vers le même fichier, alors que 2>&1 > fichier renvoie le flot de sortie d'erreur vers la destination du flot de sortie standard avant de rediriger le flot de sortie standard vers le fichier donné.