Chapitre 3. Caractères spéciaux

Caractères spéciaux se trouvant dans les scripts et ailleurs

#

Commentaire. Les lignes commençant avec un # (à l'exception de #!) sont des commentaires.

# Cette ligne est un commentaire.

Les commentaires peuvent apparaître en fin de ligne.

echo "Un commentaire va suivre." # Un commentaire ici.

Les commentaires peuvent aussi suivre un blanc au début d'une ligne.

	# Une tabulation précède ce commentaire.

Attention

Un commentaire ne peut pas être suivi d'une commande sur la même ligne. Il n'existe pas de façon de terminer le commentaire, pour que le << vrai code >> commence dans la même ligne. Utilisez une nouvelle ligne pour la commande suivante.

Note

Bien sûr, un # échappé dans une instruction echo ne commence pas un commentaire. De la même manière, un # apparaît dans certaines constructions de substitution de paramètres et dans les expressions numériques constantes.
echo "Le # ici ne commence pas un commentaire."
echo 'Le # ici ne commence pas un commentaire.'
echo Le \# ici ne commence pas un commentaire.
echo Le # ici commence un commentaire.

echo ${PATH#*:}       # Substitution de paramètres, pas un commentaire.
echo $(( 2#101011 ))  # Conversion de base, pas un commentaire.

# Merci, S.C.
Les caractères standard de guillemet et d'échappement (" ' \) échappent le #.

Certaines opérations de filtrage de motif font aussi appel au #.

;

Séparateur de commande. [point-virgule] Permet de placer deux commandes ou plus sur la même ligne.

echo bonjour; echo ici

Notez que le << ; >> a parfois besoin d'être échappé.

;;

Terminateur dans une sélection par cas case. [double point-virgule]

case "$variable" in
abc)  echo "$variable = abc" ;;
xyz)  echo "$variable = xyz" ;;
esac

.

Commande << point >>. [point] Équivalent à source (voir Exemple 11-18). C'est une commande intégrée de Bash.

.

<< Point >>, comme composant d'un nom de fichier. Dans les noms de fichiers, le point sert de préfixe aux fichiers << cachés >>, qui sont les fichiers que ls ne montre normalement pas.
bash$ touch .fichier_caché
bash$ ls -l	      
total 10
 -rw-r--r--    1 bozo      4034 Jul 18 22:04 donnée1.carnet_d_adresses
 -rw-r--r--    1 bozo      4602 May 25 13:58 donnée1.carnet_d_adresses.bak
 -rw-r--r--    1 bozo       877 Dec 17  2000 boulot.carnet_d_adresse


bash$ ls -al	      
total 14
 drwxrwxr-x    2 bozo  bozo      1024 Aug 29 20:54 ./
 drwx------   52 bozo  bozo      3072 Aug 29 20:51 ../
 -rw-r--r--    1 bozo      4034 Jul 18 22:04 donnée1.carnet_d_adresses
 -rw-r--r--    1 bozo      4602 May 25 13:58 donnée1.carnet_d_adresses.bak
 -rw-r--r--    1 bozo       877 Dec 17  2000 boulot.carnet_d_adresse
 -rw-rw-r--    1 bozo  bozo         0 Aug 29 20:54 .fichier_caché
	        

En ce qui concerne les noms des répertoires, un seul point représente le répertoire courant, et deux points de suite indiquent le répertoire parent.

bash$ pwd
/home/bozo/projets

bash$ cd .
bash$ pwd
/home/bozo/projets

bash$ cd ..
bash$ pwd
/home/bozo/
	        

Le point apparaît souvent comme répertoire de destination d'une commande de déplacement de fichiers.

bash$ cp /home/bozo/travail_en_cours/débarras/* .
	        

.

Filtrage d'un caractère par le << point >>. Pour le filtrage de caractères au sein d'une expression régulière, un << point >> correspond à un seul caractère.

"

Citation partielle. [guillemet double] "CHAÎNE" empêche l'interprétation de la plupart des caractères spéciaux présents dans la CHAÎNE. Voir aussi Chapitre 5.

'

Citation totale. [guillemet simple] 'CHAÎNE' empêche l'interprétation de tous les caractères spéciaux présents dans la CHAÎNE. Ces guillemets sont plus puissants que ". Voir aussi Chapitre 5.

,

Opérateur virgule. L'opérateur virgule relie une suite d'opérations arithmétiques. Toutes sont évaluées, mais seul le résultat de la dernière est renvoyé.
let "t2 = ((a = 9, 15 / 3))"  # Initialise "a" et calcule "t2".

\

Échappement. [anti-slash] \X << échappe >> le caractère X. Cela a pour effet de << mettre X entre guillemets >>, et est équivalent à 'X'. Le \ peut être utilisé pour mettre " et ' entre guillemets, pour pouvoir les écrire sous forme littérale.

Voir Chapitre 5 pour une explication plus détaillée des caractères échappés.

/

Séparateur du chemin d'un fichier. [barre oblique] Sépare les composants d'un nom de fichier (comme dans /home/bozo/projets/Makefile).

C'est aussi l'opérateur arithmétique de division.

`

Substitution de commandes. [guillemet inversé] `commande` rend la sortie de commande disponible pour initialiser une variable. Connu sous le nom de guillemets inversés.

:

Commande nulle. [deux-points] Il s'agit de l'équivalent shell d'un << NOP >> (no op, c'est-à-dire << pas d'opération >>). Elle peut être considérée comme un synomyme pour la commande intégrée true. La commande << : >> est elle-même une commande intégrée Bash, et son état de sortie est << vrai >> (0).

:
echo $?   # 0

Boucle sans fin :

while :
do
   operation-1
   operation-2
   ...
   operation-n
done

# Identique à :
#    while true
#    do
#      ...
#    done

Sert de bouche-trou dans un test if/then:

if condition
then :   # Ne rien faire et continuer
else
   faire_quelque_chose
fi

Sert de bouche-trou quand on attend une opération binaire, voir Exemple 8-2 et les paramètres par défaut.

: ${nom_utilisateur=`whoami`}
# ${nom_utilisateur=`whoami`}   sans les deux-points en tout début donne une erreur
#                               sauf si "nom_utilisateur" est une commande, intégrée ou non...

Sert de bouche-trou quand on attend une commande dans un document en ligne. Voir Exemple 17-9.

Évalue une suite de variables en utilisant la substitution de paramètres (comme dans Exemple 9-13).
: ${HOSTNAME?} ${USER?} ${MAIL?}
# Affiche un message d'erreur si une variable d'environnement (ou plusieurs) n'est pas initialisée.

Expansion de variable / remplacement d'une sous-chaîne.

En combinaison avec l'opérateur de redirection >, tronque un fichier à la taille zéro, sans changer ses permissions. Crée le fichier s'il n'existait pas auparavant.
: > données.xxx   # Fichier "données.xxx" maintenant vide

# Même effet que cat /dev/null >données.xxx
# Néanmoins, cela ne crée pas un nouveau processus, car ":" est une commande intégrée.
Voir aussi Exemple 12-11.

En combinaison avec l'opérateur de redirection >>, met à jour la date et l'heure de modification et d'accès (: >> nouveau_fichier). Crée le fichier s'il n'existait pas. C'est équivalent à touch.

Note

Cela s'applique aux fichiers réguliers, mais pas aux tubes, aux liens symboliques et à certains fichiers spéciaux.

Peut servir à commencer une ligne de commentaire bien que ce ne soit pas recommandé. Utiliser # pour un commentaire désactive la vérification d'erreur pour le reste de la ligne, donc vous pouvez y mettre pratiquement n'importe quoi. En revanche ce n'est pas le cas avec :.
: Voici est un commentaire qui cause une erreur, ( if [ $x -eq 3] ).

Le << : >> sert aussi de séparateur de champ, dans /etc/passwd et dans la variable $PATH.
bash$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games

!

Inverse le sens d'un test ou d'un état de sortie. L'opérateur ! inverse l'état de sortie de la commande à laquelle il est appliqué (voir Exemple 6-2). Il inverse aussi la conclusion d'un opérateur de test. Cela peut, par exemple, changer le sens d'un << égal >> ( = ) en un << différent >> ( != ). L'opérateur ! est un mot-clé Bash.

Dans un autre contexte, le ! apparaît aussi dans les références indirectes de variable.

Dans un contexte encore différent, à partir de la ligne de commande, le ! appelle le mécanisme d'historique de Bash (voir Annexe F). Notez que dans un script, ce mécanisme est désactivé.

*

Joker. [astérisque] Le caractère * sert de << joker >> pour l'expansion des noms de fichiers dans le remplacement. Utilisé seul, il correspond à tous les noms de fichiers d'un répertoire donné.

bash$ echo *
abs-book.sgml add-drive.sh agram.sh alias.sh
	      

L'astérisque * représente aussi tout un ensemble (parfois vide) de caractères dans une expression régulière.

*

Opérateur arithmétique. Dans le contexte des opérations arithmétiques, * est une multiplication.

La double astérisque ** est l'opérateur exponentiel.

?

Opérateur de test. A l'intérieur de certaines expressions, le ? indique un test pour une condition.

Dans une construction entre parenthèses doubles, ? sert d'opérateur à trois arguments dans le style du C. Voir Exemple 9-28.

Dans une expression de substitution de paramètres, le ? teste si une variable a été initialisée.

?

Joker. Le caractère ? sert de joker pour un seul caractère pour l'expansion d'un nom de fichier dans un remplacement, et également représente un caractère dans une expression régulière étendue.

$

Substitution de variable.
var1=5
var2=23skidoo

echo $var1     # 5
echo $var2     # 23skidoo

Un $ préfixant un nom de variable donne la valeur que contient cette variable.

$

Fin de ligne. Dans une expression régulière, un $ signifie la fin d'une ligne de texte.

${}
$*, $@
$?

Variable contenant l'état de sortie. La variable $? contient l'état de sortie d'une commande, d'une fonction ou d'un script.

$$

Variable contenant l'identifiant du processus. La variable $$ contient le numéro de processus du script dans lequel elle apparaît.

()

Groupe de commandes.
(a=bonjour; echo $a)

Important

Une liste de commandes entre parenthèses lance un sous-shell.

Les variables comprises dans ces parenthèses, à l'intérieur du sous-shell, ne sont pas visibles par le reste du script. Le processus parent, le script, ne peut pas lire les variables créées dans le processus fils, le sous-shell.
a=123
( a=321; )	      

echo "a = $a"   # a = 123
# "a" à l'intérieur des parenthèses agit comme une variable locale.

Initialisation de tableaux.
Array=(element1 element2 element3)

{xxx, yyy, zzz, ...}

Expansion d'accolades.
grep Linux fichier*.{txt,htm*}
# Trouve toutes les instances du mot "Linux"
# dans les fichiers "fichierA.txt", "fichier2.txt", "fichierR.html", "fichier-87.htm", etc.

Une commande peut agir sur un liste de fichiers séparés par des virgules à l'intérieur d'accolades [1]. L'expansion de noms de fichiers (remplacement) s'applique aux fichiers contenus dans les accolades.

Attention

Aucune espace n'est autorisée à l'intérieur des accolades sauf si les espaces sont comprises dans des guillemets ou échappées.

echo {fichier1,fichier2}\ :{\ A," B",' C'}

fichier1 : A fichier1 : B fichier1 : C fichier2 : A fichier2 : B fichier2 : C

{}

Bloc de code. [accolade] Aussi connu sous le nom de << groupe en ligne >>, cette construction crée une fonction anonyme. Néanmoins, contrairement à une fonction, les variables d'un bloc de code restent visibles par le reste du script.

bash$ { local a; a=123; }
bash: local: can only be used in a function
	      

a=123
{ a=321; }
echo "a = $a"   # a = 321   (valeur à l'intérieur du bloc de code)

# Merci, S.C.

Le bloc de code entouré par des accolades peut utiliser la redirection d'E/S (entrées/sorties).

Exemple 3-1. Blocs de code et redirection d'E/S

#!/bin/bash
# Lit les lignes dans /etc/fstab.

Fichier=/etc/fstab

{
read ligne1
read ligne2
} < $Fichier

echo "La première ligne dans $Fichier est :"
echo "$ligne1"
echo
echo "La deuxième ligne dans $Fichier est :"
echo "$ligne2"

exit 0

Exemple 3-2. Sauver le résultat d'un bloc de code dans un fichier

#!/bin/bash
# rpm-check.sh

#  Recherche une description à partir d'un fichier rpm, et s'il peut être
#+ installé.
#+ Sauvegarde la sortie dans un fichier.
# 
#+ Ce script illustre l'utilisation d'un bloc de code.

SUCCES=0
E_SANSARGS=65

if [ -z "$1" ]
then
	echo "Usage: `basename $0` fichier-rpm"
  exit $E_SANSARGS
fi  

{ 
  echo
  echo "Description de l'archive :"
  rpm -qpi $1       # Requête pour la description.
  echo
  echo "Liste de l'archive :"
  rpm -qpl $1       # Requête pour la liste.
  echo
  rpm -i --test $1  # Requête pour savoir si le fichier rpm est installable.
  if [ "$?" -eq $SUCCES ]
  then
    echo "$1 est installable."
  else
    echo "$1 n'est pas installable."
  fi  
  echo
} > "$1.test"       # Redirige la sortie de tout le bloc vers un fichier.

echo "Les résultats du test rpm sont dans le fichier $1.test"

# Voir la page de manuel de rpm pour des explications sur les options.

exit 0

Note

Contrairement à un groupe de commandes entre parenthèses, comme ci-dessus, un bloc de code entouré par des accolades ne sera pas lancé dans un sous-shell. [2]

{} \;

Chemin. Principalement utilisé dans les constructions find. Ce n'est pas une commande intégrée du shell.

Note

Le << ; >> termine l'option -exec d'une séquence de commandes find. Il a besoin d'être échappé pour que le shell ne l'interprète pas.

[ ]

Test.

Teste l'expression entre [ ]. Notez que [ fait partie de la commande intégrée test (et en est un synonyme), ce n'est pas un raccourci vers la commande externe /usr/bin/test.

[[ ]]

Test.

Teste l'expression entre [[ ]] (mot-clé du shell).

Voir les explications sur la structure [[ ... ]].

[ ]

Élément d'un tableau.

Accolés au nom d'un tableau, les crochets indiquent l'indice d'un élément.
Tableau[1]=slot_1
echo ${Tableau[1]}

[ ]

suite de caractères.

Dans une expression régulière, les crochets désignent une suite continue de caractères devant servir de motif.

(( ))

Expansion d'entiers.

Développe et évalue une expression entière entre (( )).

Voir les explications sur la structure (( ... )).

> &> >& >> <

nom_script >nom_fichier redirige la sortie de nom_script vers le fichier nom_fichier et écrase nom_fichier s'il existe déjà.

commande &>nom_fichier redirige à la fois stdout et stderr de commande vers nom_fichier.

commande >&2 redirige stdout de commande vers stderr.

nom_script >>nom_fichier ajoute la sortie de nom_script à la fin du fichier nom_fichier. Si le fichier n'existe pas déjà, il sera créé.

(commande)>

<(commande)

Dans un autre contexte, les caractères < et > agissent comme des opérateurs de comparaison de chaînes de caractères.

Dans un contexte encore différent, les caractères < et > agissent comme des opérateurs de comparaison d'entiers. Voir aussi Exemple 12-6.

<<

Redirection utilisée dans un document en ligne.

<, >

Comparaison ASCII.
leg1=carottes
leg2=tomates

if [[ "$leg1" < "$leg2" ]]
then
  echo "Le fait que $leg1 précède $leg2 dans le dictionnaire"
  echo "n'a rien à voir avec mes préférences culinaires."
else
  echo "Mais quel type de dictionnaire utilisez-vous?"
fi

\<, \>

bash$ grep '\<mot\>' fichier_texte

|

Tube. Passe la sortie de la commande précédente à l'entrée de la suivante. Cette méthode permet de chaîner les commandes ensemble.

echo ls -l | sh
#  Passe la sortie de "echo ls -l" au shell
#+ avec le même résultat qu'un simple "ls -l".


cat *.lst | sort | uniq
#  Assemble et trie tous les fichiers ".lst", puis supprime les lignes
#+ dupliquées.

La sortie d'une commande ou de plusieurs commandes doit être envoyée à un script via un tube.
#!/bin/bash
# uppercase.sh : Change l'entrée en majuscules.

tr 'a-z' 'A-Z'
#  La plage de lettres doit être entre guillemets pour empêcher que la
#+ génération des noms de fichiers ne se fasse que sur les fichiers à un
#+ caractère.

exit 0
Maintenant, envoyons par le tube la sortie de ls -l à ce script.
bash$ ls -l | ./uppercase.sh
-RW-RW-R--    1 BOZO  BOZO       109 APR  7 19:49 1.TXT
 -RW-RW-R--    1 BOZO  BOZO       109 APR 14 16:48 2.TXT
 -RW-R--R--    1 BOZO  BOZO       725 APR 20 20:56 FICHIER-DONNEES
	      

Note

Le canal stdout de chaque processus dans un tube doit être lu comme canal stdin par le suivant. Si ce n'est pas le cas, le flux de données va se bloquer et le tube ne se comportera pas comme il devrait.
cat fichier1 fichier2 | ls -l | sort
# La sortie à partir de "cat fichier1 fichier2" disparaît.

Un tube tourne en tant que processus fils, et ne peut donc modifier les variables du script.
variable="valeur_initiale"
echo "nouvelle_valeur" | read variable
echo "variable = $variable"     # variable = valeur_initiale

Si une des commandes du tube échoue, l'exécution du tube se termine prématurément. Dans ces conditions, on a un tube cassé et on envoie un signal SIGPIPE.

>|

Force une redirection (même si l' option noclobber est mise en place). Ceci va forcer l'écrasement d'un fichier déjà existant.

||

Opérateur OU logique. Dans une structure de test , l'opérateur || a comme valeur de retour 0 (succès) si l'un des deux est vrai.

&

Faire tourner la tâche en arrière-plan. Une commande suivie par un & fonctionnera en tâche de fond.

bash$ sleep 10 &
[1] 850
[1]+  Done                    sleep 10
	      

A l'intérieur d'un script, les commandes et même les boucles peuvent tourner en tâche de fond.

Exemple 3-3. Lancer une boucle en tâche de fond

#!/bin/bash
# background-loop.sh

for i in 1 2 3 4 5 6 7 8 9 10            # Première boucle.
do
  echo -n "$i "
done & # Lance cette boucle en tâche de fond.
       # S'exécutera quelques fois après la deuxième boucle.

echo   # Ce 'echo' ne s'affichera pas toujours.

for i in 11 12 13 14 15 16 17 18 19 20   # Deuxième boucle.
do
  echo -n "$i "
done  

echo   # Ce 'echo' ne s'affichera pas toujours.

# ======================================================

# La sortie attendue de ce script:
# 1 2 3 4 5 6 7 8 9 10 
# 11 12 13 14 15 16 17 18 19 20 

# Mais, quelque fois, vous obtenez:
# 11 12 13 14 15 16 17 18 19 20 
# 1 2 3 4 5 6 7 8 9 10 bozo $
# (Le deuxième 'echo' ne s'exécute pas. Pourquoi?)

# Occasionnellement aussi:
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# (Le premier 'echo' ne s'exécute pas. Pourquoi?)

# Et très rarement:
# 11 12 13 1 2 3 4 5 6 7 8 9 10 14 15 16 17 18 19 20 
# La boucle en avant plan s'exécute avant celle en tâche de fond.

exit 0

Attention

Une commande tournant en tâche de fond à l'intérieur d'un script peut faire s'arrêter le script, attendant un appui sur une touche. Heureusement, il est possible d'y remède.

&&

Opérateur ET logique. Dans une structure de test, l'opérateur && renvoie 0 (succès) si et seulement si les deux conditions sont vraies.

-

Option, préfixe. Introduit les options pour les commandes ou les filtres. Sert aussi de préfixe pour un opérateur.

COMMANDE -[Option1][Option2][...]

ls -al

sort -dfu $nom_fichier

set -- $variable

if [ $fichier1 -ot $fichier2 ]
then
  echo "Le fichier $fichier1 est plus ancien que le $fichier2."
fi

if [ "$a" -eq "$b" ]
then
  echo "$a est égal à $b."
fi

if [ "$c" -eq 24 -a "$d" -eq 47 ]
then
  echo "$c vaut 24 et $d vaut 47."
fi

-

Redirection à partir de ou vers stdin ou stdout. [tiret]

(cd /source/repertoire && tar cf - . ) | (cd /dest/repertoire && tar xpvf -)
# Déplace l'ensemble des fichiers d'un répertoire vers un autre
# [courtoisie d'Alan Cox <a.cox@swansea.ac.uk>, avec une modification mineure]

# 1) cd /source/repertoire   Répertoire source, où se trouvent les fichiers à
#                            déplacer.
# 2) &&                      "ET de liste": si l'opération 'cd' a fonctionné,
#							 alors il exécute la commande suivante.
# 3) tar cf - .              L'option 'c' de la commande d'archivage 'tar' crée
#                            une nouvelle archive,
#                            l'option 'f' (fichier), suivie par '-' désigne
#                            stdout comme fichier cible.
#                            et place l'archive dans le répertoire courant ('.').
# 4) |                       Tube...
# 5) ( ... )                 Un sous-shell.
# 6) cd /dest/repertoire     Se déplace dans le répertoire de destination.
# 7) &&                      "ET de liste", comme ci-dessus.
# 8) tar xpvf -              Déballe l'archive ('x'), préserve l'appartenance
#                            et les droits des fichiers ('p'),
#                            puis envoie de nombreux messages vers stdout ('v'),
#                            en lisant les données provenant de stdin
#                            ('f' suivi par un '-').
#
#                            Notez que 'x' est une commande, et 'p', 'v', 'f'
#                            sont des options.
# Ouf !



# Plus élégant, mais équivalent à:
#   cd source-repertoire
#   tar cf - . | (cd ../repertoire-source; tar xzf -)
#
# cp -a /source/repertoire /dest     a aussi le même effet.

bunzip2 linux-2.4.3.tar.bz2 | tar xvf -
# --décompresse l'archive--  | --puis la passe à "tar"--
# Si "tar" n'a pas intégré le correctif de support de "bunzip2",
# il faut procéder en deux étapes distinctes avec un tube.
# Le but de cet exercice est de désarchiver les sources du noyau compressées
# avec bzip2.

Notez que dans ce contexte le signe << - >> n'est pas en lui-même un opérateur Bash, mais plutôt une option reconnue par certains utilitaires UNIX qui écrivent dans stdout ou lisent dans stdin, tels que tar, cat, etc.

bash$ echo "quoiquecesoit" | cat -
quoiquecesoit 

Lorsqu'un nom de fichier serait attendu, un - redirige la sortie vers stdout (vous pouvez le rencontrer avec tar cf), ou accepte une entrée de stdin, plutôt que d'un fichier. C'est une méthode pour utiliser un outil principalement destiné à manipuler des fichiers comme filtre dans un tube.

bash$ file
Usage: file [-bciknvzL] [-f namefile] [-m magicfiles] file...
	      
Tout seul sur la ligne de commande, file échoue avec un message d'erreur.

Ajoutez un << - >> pour pouvoir vous en servir. Le shell attend alors une entrée de l'utilisateur.
bash$ file -
abc
standard input:              ASCII text



bash$ file -
#!/bin/bash
standard input:              Bourne-Again shell script text executable
	      
Maintenant la commande accepte une entrée de stdin et l'analyse.

Le << - >> peut être utilisé pour envoyer stdout à d'autres commandes via un tube, ce qui permet quelques astuces comme l'ajout de lignes au début d'un fichier.

Par exemple vous pouvez utiliser diff pour comparer un fichier avec une partie d'un autre fichier :

grep Linux fichier1 | diff fichier2 -

Finalement, un exemple réel utilisant - avec tar.

Exemple 3-4. Sauvegarde de tous les fichiers modifiés dans les dernières 24 heures

#!/bin/bash

#  Sauvegarde dans une archive tar compressée tous les fichiers
#+ du répertoire courant modifiés dans les dernières 24 heures.

FICHIERSAUVE=backup
archive=${1:-$FICHIERSAUVE}
#  Si aucun nom de fichier n'est spécifié sur la ligne de commande,
#+ nous utiliserons par défaut "backup.tar.gz."

tar cvf - `find . -mtime -1 -type f -print` > $archive.tar
gzip $archive.tar
echo "Répertoire $PWD sauvegardé dans un fichier archive \"$archive.tar.gz\"."


#  Stephane Chazelas indique que le code ci-dessus échouera si il existe trop
#+ de fichiers ou si un nom de fichier contient des espaces blancs.

# Il suggère les alternatives suivantes:
# -------------------------------------------------------------------
#   find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
#         avec la version GNU de "find".


#   find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;
#         portable aux autres UNIX, mais plus lent.
# -------------------------------------------------------------------


exit 0

Attention

Les noms de fichiers commençant avec un << - >> peuvent poser problème lorsqu'ils sont couplés avec le << - >> opérateur de redirection. Votre script doit détecter de tels fichiers et leur ajouter un préfixe approprié, par exemple ./-NOMFICHIER, $PWD/-NOMFICHIER, ou $NOMCHEMIN/-NOMFICHIER.

Il y aura probablement un problème si la valeurx d'une variable commence avec un -.
var="-n"
echo $var		
# A le même effet qu'un "echo -n" et donc n'affiche rien.

-

Répertoire courant précédent. [tiret] cd - revient au répertoire précédent, en utilisant la variable d'environnement $OLDPWD.

Attention

Ne confondez pas << - >> utilisé dans ce sens avec l'opérateur de redirection << - >> vu précédemment. L'interprétation du << - >> dépend du contexte dans lequel il apparaît.

-

Moins. Le signe moins est une opération arithmétique.

=

Égal. Opérateur d'affectation.
a=28
echo $a   # 28

Dans un autre contexte, le signe = est un opérateur de comparaison de chaînes de caractères.

+

Plus. Opérateur arithmétique d'addition.

Dans un autre contexte, le + est un opérateur d'expression régulière.

+

Option. Option pour une commande ou un filtre.

Certaines commandes, intégrées ou non, utilisent le + pour activer certaines options et le - pour les désactiver.

%

Modulo. Opérateur arithmétique modulo (reste d'une division entière).

Dans un autre contexte, le % est un opérateur de reconnaissance de modèles.

~

Répertoire de l'utilisateur. [tilde] Le ~ correspond à la variable interne $HOME. ~bozo est le répertoire de l'utilisateur bozo, et ls ~bozo liste son contenu. ~/ est le répertoire de l'utilisateur courant et ls ~/ liste son contenu.
bash$ echo ~bozo
/home/bozo

bash$ echo ~
/home/bozo

bash$ echo ~/
/home/bozo/

bash$ echo ~:
/home/bozo:

bash$ echo ~utilisateur-inexistant
~utilisateur-inexistant
	      

~+

Répertoire courant. Correspond à la variable interne $PWD.

~-

Répertoire courant précédent. Correspond à la variable interne $OLDPWD.

^

Début de ligne. Dans une expression régulière, un << ^ >> correspond au début d'une ligne de texte.

Caractères de contrôle

Modifient le comportement d'un terminal ou de l'affichage d'un texte. Un caractère de contrôle est une combinaison CONTROL + touche.

  • Ctrl-C

    Termine un job en avant-plan.

  • Ctrl-D

    Se déconnecte du shell (similaire à un exit).

    C'est le caractère << EOF >> (End Of File, fin de fichier), qui termine aussi l'entrée de stdin.

  • Ctrl-G

    << CLOCHE >> (bip).

  • Ctrl-H

    Backspace.

    #!/bin/bash
    # Intègre Ctrl-H dans une chaîne de caractères.
    
    a="^H^H"                  # Deux Ctrl-H's (backspaces).
    echo "abcdefg"             # abcdefg
    echo -n "abcdefg$a "       # abcd fg
    # Espace à la fin ^              ^ Deux fois backspaces.
    echo -n "abcdefg$a"        # abcdefg
    #  Pas d'espace à la fin           Ne fait pas de backspace (pourquoi?).
                          # Les résultats pourraient ne pas être ceux attendus.
    echo; echo

  • Ctrl-J

    Retour chariot.

  • Ctrl-L

    Formfeed (efface l'écran du terminal), a le même effet que la commande clear.

  • Ctrl-M

    Nouvelle ligne.

  • Ctrl-U

    Efface une ligne de l'entrée.

  • Ctrl-Z

    Met en pause un job en avant-plan.

Espace blanc

Fonctionne comme un séparateur, séparant les commandes ou les variables. Les espaces blancs sont constitués d'espaces, de tabulations, de lignes blanches ou d'une combinaison de ceux-ci. Dans certains contextes, tels que les affectations de variable, les espaces blancs ne sont pas permis, et sont considérés comme une erreur de syntaxe.

Les lignes blanches n'ont aucun effet sur l'action d'un script, et sont plutôt utiles pour séparer visuellement les différentes parties.

La variable $IFS est une variable spéciale définissant pour certaines commandes le séparateur des champs en entrée. Elle a pour valeur par défaut un espace blanc.

Notes

[1]

Le shell fait l'expansion des accolades. La commande elle-même agit sur le résultat de cette expansion.

[2]

Exception : un bloc de code entre accolades dans un tube peut être lancé comme sous-shell.
ls | { read ligne1; read ligne2; }
# Erreur. Le bloc de code entre accolades tourne comme un sous-shell,
# donc la sortie de "ls" ne peut être passée aux variables de ce bloc.
echo "La première ligne est $ligne1; la seconde ligne est $ligne2"  # Ne fonctionnera pas.

# Merci, S.C.