• Aucun résultat trouvé

$IFS et espaces blancs

Dans le document Guide avancé d'écriture des scripts Bash (Page 78-84)

Partie Part 3. Après l'approche basique

Exemple 9.1. $IFS et espaces blancs

(Affiche un espace blanc -- un espace, ^I [tabulation horizontale], ou un retour chariot -- et affiche un dollar ($) en fin de ligne.)

bash$ bash -c 'set w x y z; IFS=":-;"; echo "$*"' w:x:y:z

(Lit les commandes à partir de la chaîne et affecte tout argument suivant les paramètres de position)

Attention

$IFSne gère pas les espaces blancs de la même façon que les autres caractères.

Exemple 9.1. $IFS et espaces blancs

#!/bin/bash

# $IFS traite les espaces blancs différemment des autres caractères.

affiche_un_argument_par_ligne() {

for arg

do echo "[$arg]"

done }

echo; echo "IFS=\" \""

echo "---"

IFS=" "

var=" a b c "

affiche_un_argument_par_ligne $var # affiche_un_argument_par_ligne `echo

" a b c "`

#

# [a]

# [b]

# [c]

echo; echo "IFS=:"

echo "---"

IFS=:

Les variables revisitées

var=":a::b:c:::" # Identique à ci-dessus, mais substitue ":" à " ".

affiche_un_argument_par_ligne $var

#

# []

# [a]

# []

# [b]

# [c]

# []

# []

# []

# La même chose arrive avec le séparateur de champs "FS" dans awk.

# Merci, Stephane Chazelas.

echo exit 0

(Merci beaucoup, Stéphane Chazelas, pour cette clarification et ces exemples.)

Voir aussi l'Exemple 15.41, « Analyser le domaine d'un courrier indésirable » , Exemple 10.7, « Un remplaçant de grep pour les fichiers binaires » et Exemple 18.14, « Analyser une boîte mail » pour des exemples instructifs sur l'utilisation de$IFS.

$IGNOREEOF

Ignore EOF : nombre de fins de fichier (control-D) que le shell va ignorer avant de déconnecter.

$LC_COLLATE

Souvent intégré dans les fichiers.bashrcou/etc/profile, cette variable contrôle l'ordre d'examen dans l'expansion des noms de fichiers et les correspondances de modèles. Si elle est mal gérée,LC_COLLATEpeut apporter des résultats inat-tendus dans le remplacement de noms de fichiers.

Note

À partir de la version 2.05 de Bash, le remplacement de noms de fichiers ne tient plus compte des lettres en mi-nuscules et en majuscules dans une suite de caractères entre crochets. Par exemple, ls [A-M]* correspondrait à la fois àFichier1.txtet àfichier1.txt. Pour annuler le comportement personnalisé de la correspon-dance par crochets, initialisezLC_COLLATEàCpar un export LC_COLLATE=Cdans/etc/profile et/ou~/.bashrc.

$LC_CTYPE

Cette variable interne contrôle l'interprétation des caractères pour le remplacement et la correspondance de modèles.

$LINENO

Cette variable correspond au numéro de ligne du script shell dans lequel cette variable apparaît. Elle n'a une signification que dans le script où elle apparait et est surtout utilisée dans les phases de débogage.

# *** DEBUT BLOC DEBUG ***

dernier_argument_command=$_ # Le sauver.

echo "À la ligne numéro $LINENO, la variable \"v1\" = $v1"

echo "Dernier argument de la ligne exécutée = $dernier_argument_command"

# *** FIN BLOC DEBUG ***

$MACHTYPE

Type de machine.

Identifie le matériel du système.

bash$ echo $MACHTYPE i686

Les variables revisitées

$OLDPWD

Ancien répertoire courant (« OLD-print-working-directory », ancien répertoire où vous étiez).

$OSTYPE

Type de système d'exploitation.

bash$ echo $OSTYPE linux

$PATH

Chemin vers les binaires, habituellement/usr/bin/,/usr/X11R6/bin/,/usr/local/bin, etc.

Lorsqu'une commande est donnée, le shell recherche automatiquement l'exécutable dans les répertoires listés dans le chemin.

Le chemin est stocké dans la variable d'environnement,$PATH, une liste des répertoires, séparés par le symbole ":". Norma-lement, le système enregistre la définition de$PATHdans /etc/profileet/ou~/.bashrc(voir l'Annexe G, Fichiers importants).

bash$ echo $PATH

/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/sbin:/usr/sbin

PATH=${PATH}:/opt/bin ajoute le répertoire /opt/bin au chemin actuel. Dans un script, il peut être avantageux d'ajouter temporairement un répertoire au chemin de cette façon. Lorsque le script se termine, le$PATHoriginal est restauré (un processus fils, tel qu'un script, ne peut pas changer l'environnement du processus père, le shell).

Note

Le « répertoire » courant,./, est habituellement omis de$PATHpour des raisons de sécurité.

$PIPESTATUS

Variable de type tableau375 contenant les codes de sortie de la dernièrecommande exécutée via un tube. De façon étonnante, ceci ne donne pas obligatoirement le même résultat que le code de sortie44 de la dernière commande exécutée.

bash$ echo $PIPESTATUS 0

bash$ ls -al | bogus_command

bash: bogus_command: command not found bash$ echo $PIPESTATUS

141

bash$ ls -al | bogus_command

bash: bogus_command: command not found bash$ echo $?

127

Les membres du tableau$PIPESTATUScontiennent le code de sortie de chaque commande respective exécutée via un tube.

$PIPESTATUS[0]contient le code de sortie de la première commande du tube,$PIPESTATUS[1]le code de sortie de la deuxième commande et ainsi de suite.

Attention

La variable$PIPESTATUSpeut contenir une valeur 0 erronée dans un shell de connexion (dans les versions précédant la 3.0 de Bash).

tcsh% bash

bash$ who | grep nobody | sort bash$ echo ${PIPESTATUS[*]}

0

Les variables revisitées

1Le PID du script en cours est$$, bien sûr.

Les lignes ci-dessus contenues dans un script produiraient le résultat attendu,0 1 0.

Merci, Wayne Pollock pour avoir partagé ceci en apportant l'exemple ci-dessus.

Note

La variable$PIPESTATUSdonne des résultats inattendus dans certains contextes.

bash$ echo $BASH_VERSION 3.00.14(1)-release

bash$ $ ls | commande_boguee | wc

bash: commande_boguee: command not found

0 0 0

bash$ echo ${PIPESTATUS[@]}

141 127 0

Chet Ramey attribue l'affichage ci-dessus au comportement de ls. Si ls écrit dans un tube dont la sortie n'est pas lue, alors SIGPIPE le tue et son code de sortie44 est 141. Sinon, son code de sortie est 0, comme attendu.

C'est certainement le cas pour tr.

Note

$PIPESTATUSest une variable « volatile ». Elle doit être immédiatement capturée après le tube, c'est-à-dire avant que d'autres commandes n'interviennent.

bash$ $ ls | commande_boguee | wc

bash: commande_boguee: command not found

0 0 0

bash$ echo ${PIPESTATUS[@]}

0 127 0

bash$ echo ${PIPESTATUS[@]}

0

Note

L'option pipefail470 pourrait être utile dans les cas où$PIPESTATUSne donne pas l'information désirée.

$PPID

Le$PPIDd'un processus est l'identifiant du processus (PID) père.1 Comparez ceci avec la commande pidof.

$PROMPT_COMMAND

Une variable contenant une commande à exécuter juste avant l'affichage de l'invite principale,$PS1.

$PS1

Ceci est l'invite principale, vue sur la ligne de commande.

$PS2

La deuxième invite, vue lorsqu'une saisie supplémentaire est attendue. Elle s'affiche comme « > ».

Les variables revisitées

$PS3

La troisième invite, affichée lors d'une boucle select (voir l'Exemple 10.29, « Créer des menus en utilisant select »)

$PS4

La quatrième invite, affichée au début de chaque ligne d'affichage lorsqu'un script a été appelé avec l'option419 -x. Elle affiche un « + ».

$PWD

Répertoire courant (répertoire où vous êtes actuellement) Ceci est analogue à la commande intégrée pwd.

#!/bin/bash

E_MAUVAIS_REPERTOIRE=73 clear # Efface l'écran.

RepertoireCible=/home/bozo/projects/GreatAmericanNovel cd $RepertoireCible

echo "Suppression des anciens fichiers de $RepertoireCible."

if [ "$PWD" != "$RepertoireCible" ]

then # Empêche la suppression d'un mauvais répertoire par accident.

echo "Mauvais répertoire!"

echo "Dans $PWD, plutôt que $RepertoireCible!"

echo "Je quitte!"

exit $E_MAUVAIS_REPERTOIRE fi

rm -rf *

rm .[A-Za-z0-9]* # Supprime les fichiers commençant par un point.

# rm -f .[^.]* ..?* pour supprimer les fichiers commençant par plusieurs points.

# (shopt -s dotglob; rm -f *) fonctionnera aussi.

# Merci, S.C., pour nous l'avoir indiqué.

# Les noms de fichier peuvent contenir tous les caractères de 0 à 255,

# à l'exception de "/".

# La suppression des fichiers commençant par des caractères bizarres est laissé

# en exercice.

# Autres opérations ici, si nécessaire.

echo

echo "Fait."

echo "Anciens fichiers supprimés de $RepertoireCible."

echo exit 0

$REPLY

La variable par défaut lorsqu'aucune n'est adjointe au read. Aussi applicable au menu select, mais renvoie seulement le numé-ro de l'élément de la variable choisie et non pas la valeur de la variable elle-même.

#!/bin/bash

# reply.sh

# REPLY est la variable par défaut d'une commande 'read' echo

echo -n "Quel est votre légume favori? "

read

echo "Votre légume favori est $REPLY."

Les variables revisitées

2Un peu analogue à la récursion365, dans ce contexte, l'imbrication réfère à un modèle embarqué à l'intérieur d'un modèle plus large. Une des définitions de nest, d'après l'édition 1913 du dictionnaire Webster, illustre très bien ceci : « une collection de boîtes, cases ou d'objets de ce type, d'une taille graduée, les unes dans les autres. »

# REPLY contient la valeur du dernier "read" si et seulement si aucune variable

#+ n'est spécifiée.

echo

echo -n "Quel est votre fruit favori? "

read fruit

echo "Votre fruit favori est $fruit."

echo "mais..."

echo "La valeur de \$REPLY est toujours $REPLY."

# $REPLY est toujours initialisé à sa précédente valeur car la variable $fruit

#+ a absorbé la nouvelle valeur obtenue par "read".

echo exit 0

$SECONDS

Le nombre de secondes pris par l'exécution du script.

#!/bin/bash LIMITE_TEMPS=10 INTERVALLE=1 echo

echo "Appuyez sur Control-C pour sortir avant $LIMITE_TEMPS secondes."

echo

while [ "$SECONDS" -le "$LIMITE_TEMPS" ] do

if [ "$SECONDS" -eq 1 ] then

unites=seconde else

unites=secondes fi

echo "Ce script tourne depuis $SECONDS $unites."

# Sur une machine lente, le script peut laisser échapper quelquefois

#+ un élément du comptage dans la boucle while.

sleep $INTERVALLE done

echo -e "\a" # Beep!

exit 0

$SHELLOPTS

La liste des options419 activées du shell, une variable en lecture seule.

bash$ echo $SHELLOPTS

braceexpand:hashall:histexpand:monitor:history:interactive-comments:emacs

$SHLVL

Niveau du shell, à quel point Bash est imbriqué.2Si, à la ligne de commande, $SHLVL vaut 1, alors dans un script, il sera in-crémenté et prendra la valeur 2.

Note

Cette variable n'est pas affectée par les sous-shells. Utilisez $BASH_SUBSHELL quand vous avez besoin d'une indication d'une imbrication de sous-shell.

Les variables revisitées

$TMOUT

Si la variable d'environnement$TMOUTest initialisée à une valeur différente de zéro appeléetime, alors l'invite shell dépas-sera son délai au bout detimesecondes. Ceci causera une déconnexion.

À partir de la version 2.05b de Bash, il est possible d'utiliser$TMOUTdans un script avec un read.

# Fonctionne avec des scripts pour Bash, versions

#+ 2.05b et ultérieures.

TMOUT=3 # L'invite s'arrête dans trois secondes.

echo "Quelle est votre chanson favorite?"

echo "Faites vite car vous n'avez que $TMOUT secondes pour répondre !"

read chanson

if [ -z "$chanson" ] then

chanson="(sans réponse)"

# Réponse par défaut.

fi

echo "Votre chanson favorite est $chanson."

Il existe d'autres façons, certaines plus complexes, pour implémenter une entrée avec temporisation. Une alternative consiste à configurer une boucle rythmée pour signaler au script la fin de l'attente. Ceci requiert aussi une routine de gestion du signal pour récupérer (voir l'Exemple 29.5, « Récupérer la sortie ») l'interruption créée par la boucle.

Dans le document Guide avancé d'écriture des scripts Bash (Page 78-84)