I.2. Ecriture de scripts

Ecrivez un script pour réaliser chacune des tâches suivantes.

Facile

Liste des répertoires à partir du répertoire personnel de l'utilisateur

Listez les répertoires et les sous rèpertoires à partir du répertoire personnel de l'utilisateur et sauvegardez le résultat dans un fichier. Compressez le fichier, demandez à l'utilisateur d'insérer une disquette et d'appuyer sur ENTER. Enfin, sauvegardez le fichier sur la disquette.

Conversion de boucles for en boucle while et en boucles until

Convertissez les boucles for de Exemple 10-1 en boucles while. Indice: stockez les données dans un tableau et parcourez les éléments du tableau.

Après avoir effectué ce << gros lifting >>, convertissez maintenant les boucles de l'exemple en boucles until.

Modification de l'espacement des lignes d'un fichier texte

Ecrivez un script qui lit chaque ligne d'un fichier cible, puis écrit la ligne sur stdout, suivie d'une ligne vide. Ceci a pour effet de doubler l'espacement des lignes du fichier.

Incluez tout le code nécessaire pour vérifier que le script obtient l'argument nécessaire en ligne de commande (un nom de fichier), et que le fichier spécifié existe.

Quand le script s'exécute correctement, modifiez-le pour tripler l'espacement des lignes du fichier cible.

Enfin, écrivez un script pour supprimer toutes les lignes vides du fichier cible.

Liste inverse

Ecrivez un script qui s'affiche lui-même sur stdout, mais à l'envers.

Décompression automatique de fichiers

A partir d'une liste de noms de fichiers donnée en entrée, cherchez sur chaque fichier cible (en analysant la sortie de la commande file) le type de compression utilisé. Puis appellez automatiquement la commande de décompression appropriée (gunzip, bunzip2, unzip, uncompress, ou autre). Si un fichier cible n'est pas compressé, affichez un message d'erreur, mais ne faites aucune autre action sur ce fichier particulier.

Identifiant unique

Générez un identifiant hexadécimal à six chiffres << unique >> pour votre ordinateur. N'utilisez pas la commande défectueuse hostid. Indice: md5sum /etc/passwd, puis sélectionnez les six premiers chiffres de la sortie.

Sauvegarde

Archivez dans une << archive tar >> (fichier *.tar.gz) tous les fichiers de votre répertoire personnel (/home/votre-nom) qui ont été modifiés dans les dernières 24 heures. Indice: utilisez find.

Premiers

Afficher (sur stdout) tous les nombres premiers entre 60000 et 63000. La sortie doit être joliment formatée en colonnes (indice: utilisez printf).

Numéros de loterie

Un type de loterie implique de choisir cinq numéros différents entre 1 et 50. Ecrivez un script générant cinq numéros pseudo-aléatoires dans cet intervalle sans doublons. Le script donnera la possibilité d'afficher les nombres sur stdout ou de les sauvegarder dans un fichier, avec la date et l'heure où cet ensemble de nombres a été généré.

Intermédiaire

Gestion de l'espace disque

Listez, un par un, tous les fichiers faisant plus de 100Ko dans l'arborescence du répertoire /home/utilisateur. Donnez à l'utilisateur la possibilité de supprimer ou de compresser le fichier, puis continuez en affichant le suivant. Ecrivez un fichier journal avec le nom de tous les fichiers supprimés et l'heure de leur suppression.

Suppression sécurisée

Ecrivez, en tant que script, une commande de suppression << sécurisée >>, srm.sh. Les fichiers dont les noms sont passés en argument sur la ligne de commande de ce script ne sont pas supprimés mais compressés s'ils ne le sont pas déjà (utilisez file pour le vérifier), puis déplacés dans un répertoire /home/utilisateur/poubelle. Lors de son appel, le script vérifie s'il existe des fichiers ayant plus de 48 heures dans ce répertoire << poubelle >> et les supprime.

Faire la monnaie

Quel est le moyen le plus efficace de faire la monnaie sur 1,68 euros en utilisant seulement les pièces en circulation courante (jusqu'à 50 centimes)? Ce sont trois pièces de 50 centimes, une de 10, une de 5 et trois de un.

A partir d'une entrée arbitraire en ligne de commande en euros et centimes ($*.??), calculez la monnaie en utilisant le plus petit nombre de pièces. Si la monnaie de votre pays n'est pas l'euro, vous pouvez utiliser votre monnaie locale à la place. Le script devra analyser l'entrèe en ligne de commande, puis la modifier en multiple de la plus petite unité monétaire (centime ou autre). Indice: jetez un oeil sur Exemple 23-4.

Equations quadratiques

Résolvez une équation << quadratique >> de la forme Ax^2 + Bx + C = 0. Créez un script qui prend comme arguments les coefficients A, B et C, et renvoie les solutions avec jusqu'à 4 chiffres après la virgule.

Indice: envoyez les coefficients via un tube à bc, en utilisant la formule bien connue x = ( -B +/- sqrt( B^2 - 4AC ) ) / 2A.

Somme des nombres correspondants

Trouvez la somme de tous les nombres de cinq chiffres (dans l'intervalle 10000-99999) contenant exactement deux des chiffres de l'ensemble suivant: { 4, 5, 6 }. Ils peuvent se répéter à l'intérieur du même nombre, et, si c'est le cas, ils sont comptés une fois à chaque occurence.

Quelques exemples de nombres correspondants: 42057, 74638 et 89515.

Nombres porte-bonheur

Un "nombre porte-bonheur" est un de ces nombres dont les chiffres pris individuellements additionnés valent 7. Par exemple, 62431 est un "nombre porte-bonheur" (6 + 2 + 4 + 3 + 1 = 16, 1 + 6 = 7). Trouvez tous les "nombres porte-bonheur" entre 1000 et 10000.

Classer par ordre alphabêtique une chaîne de caractères

Classez par ordre alphabêtique (suivant l'ordre ASCII) une chaîne de caractères arbitraire lue sur la ligne de commande.

Analyse

Analysez /etc/passwd, et affichez son contenu sous la forme d'un joli tableau, facile à lire.

Mise en forme de l'affichage d'un fichier de données

Certaines bases de données et tableurs utilisent des fichiers de sauvegarde avec des valeurs séparées par des virgules (CSV). D'autres applications ont souvent besoin d'analyser ces fichiers.

A partir d'un fichier de données au format CSV, de la forme:
Jones,Bill,235 S. Williams St.,Denver,CO,80221,(303) 244-7989
Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612
...
Reformattez les données et affichez les sur stdout avec des colonnes disposant d'un titre et de même largeur.

Justification

A partir d'une entrée texte au format ASCII provenant soit de stdin soit d'un fichier, justifiez à droite chaque ligne suivant une longueur de ligne spécifiée par l'utilisateur en ajustant l'espacement entre les mots et envoyez la sortie sur stdout.

Liste de diffusion

En utilisant la commande mail, écrivez un script gérant une liste de diffusion simple. Le script envoie automatiquement par courrier électronique la lettre d'informations mensuelle de la compagnie, lue à partir d'un fichier texte spécifié aux adresses de la liste de diffusion que le script lit à partir d'un autre fichier spécifié.

Mots de passe

Générez des mots de passe de huit caractères pseudo-aléatoires, en utilisant les caractères contenus dans les intervalles [0-9], [A-Z], [a-z]. Chaque mot de passe doit contenir au moins deux chiffres.

Difficile

Journal des accès aux fichiers

Tracez tous les accès aux fichiers dans /etc sur une journée. Ce journal devra inclure le nom du fichier, le nom de l'utilisateur, et l'heure d'accès. Il doit aussi être indiqué si le fichier est modifié. Ecrivez cette information en enregistrements bien mis en forme dans un fichier journal.

Suppression des commentaires

Supprimez tous les commentaires d'un script shell dont le nom est spécifié en ligne de commande. Notez que la << ligne #! >> ne doit pas subir le même traitement.

Conversion HTML

Convertissez un fichier texte donné en HTML. Ce script non interactif insère automatiquement toutes les balises HTML appropriées dans un fichier spécifié en argument.

Suppression des balises HTML

Supprimez toutes les balises HTML d'un fichier, puis reformattez le en lignes de 60 à 75 caractères de longueur. Réajustez les espacementss de paragraphes et de blocs de façon appropriée, et convertissez les tables HTML en leur équivalent texte approximatif.

Conversion XML

Convertissez un fichier XML à la fois en HTML et en texte.

Chasse aux spammeurs

Ecrivez un script qui analyse un courrier électronique spam en faisant des recherches DNS à partir de l'adresse IP spécifiée dans les en-têtes pour identifier les hôtes relais ainsi que le fournisseur d'accès internet (FAI) d'origine. Le script renverra le message de spam non modifié aux FAI responsables. Bien sûr, il sera nécessaire de filtrer les adresses IP de votre propre FAI, si vous ne voulez pas vous plaindre de vous-même.

Si nécessaire, utilisez les commandes d'analyse réseau appropriées.

Code Morse

Convertissez un fichier texte en code Morse. Chaque caractère du fichier texte sera représenté par le code Morse correspondant, un ensemble de points et de tirets bas, séparé par un espace blanc du suivant. Par exemple << script >> ===> << ... _._. ._. .. .__. _ >>.

Dump Hexa

Faites une sortie hexa(décimale) d'un fichier binaire donné en argument. La sortie devra être en colonnes, le premier champ indiquant l'adresse, chacun des huit champs suivants un nombre hexa de quatre octets, et le dernier champ l'équivalent ASCII des huit champs précédents.

Emulation d'un registre à décalage

En s'inspirant de Exemple 26-7, écrivez un script qui émule un registre à décalage de 64 bits par un tableau. Implémentez des fonctions pour charger le registre, décaler à gauche et décaler à droite. Enfin, écrivez une fonction qui interprète le contenu du registre comme huit caractères ASCII sur 8 bits.

Déterminant

Résolvez un déterminant 4 x 4.

Mots cachés

Ecrivez un générateur de puzzle de << recherche de mots >>, un script qui cache dix mots d'entrée dans une matrice de 10 x 10 lettres choisies au hasard. Les mots peuvent être cachés en horizontal, en vertical et en diagonale.

Anagramme

Faites un anagramme des quatre lettres d'entrée. Par exemple, les anagrammes de word sont: do or rod row word. Vous pouvez utiliser /usr/share/dict/linux.words comme liste de référence.

Index 'brouillard'

L'<< index brouillard >> d'un passage de texte permet d'estimer sa difficulté de lecture, par un nombre correspondant grossièrement à un niveau d'école. Par exemple, un passage d'index 12 devrait être compréhensible par tout personne ayant plus de 12 ans d'école.

La version 'Gunning' de cet index utilise l'algorithme suivant.

  1. Choisissez une section de texte d'au moins 100 mots de longueur.

  2. Comptez le nombre de phrases (une portion d'une phrase tronquée par les limites de la section de texte compte pour un).

  3. Trouvez le nombre moyen de mots par phrase.

    MOY_MOT_PHRASE = TOTAL_MOTS / PHRASES

  4. Comptez le nombre de mots << difficiles >> dans le segment -- ceux contenant au moins trois syllabes. Divisez cette quantité par le nombre total de mots pour obtenir la proportion de mots difficiles.

    PRO_MOTS_DIFFIC = MOTS_LONGS / TOTAL_MOTS

  5. L'index 'Gunning' est la somme des deux quantités ci-dessus, multiplié par 0,4, arrondie à l'entier le plus proche.

    G_FOG_INDEX = int ( 0.4 * ( MOY_MOT_PHRASE + PRO_MOTS_DIFFIC ) )

L'étape 4 est de loin la partie la plus difficile de cet exercice. Il existe différents algorithmes pour estimer le nombre de syllabes dans un mot. Un moyen empirique consiste à considérer le nombre de lettres dans un mot et le mélange voyelles - consonnes.

Une stricte interprétation de l'index 'Gunning' ne compte pas les mots composés et les noms propres comme des mots << difficiles >>, mais cela compliquerait considérablement le script.

Calculer PI en utilisant l'aiguille de Buffon

Le mathématicien français du 18è siècle Buffon a conçu une expérimentation nouvelle. Lâchez de manière répétée une aiguille de longueur << n >> sur un sol en bois composé de planches longues et étroites. Les trous séparant les planches de largeur égale sont à une distance fixe << d >> les uns des autres. Gardez une trace du nombre de lâchés et du nombre de fois où l'aiguille fait une intersection avec un trou sur le sol. Le ratio de ces deux nombres se trouve être un multiple fractionnel de PI.

Dans l'esprit de l'Exemple 12-35, écrivez un script qui lance une simulation de Monte Carlo de l'aiguille de Buffon. Pour simplifier le problème, initialisez la longueur de l'aiguille à la distance entre les trous, n = d.

Indice: il existe en fait deux variables critiques: la distance du centre de l'aiguille au trou le plus proche, et l'angle formé par l'aiguille et le trou. Vous pouvez utiliser bc pour réaliser les calculs.

Cryptage Playfair

Implémentez le cryptage Playfair (Wheatstone) dans un script.

Le cryptage Playfair crypte le texte par substitution de chaque << diagramme >> de deux lettres (groupe). Traditionnellement, on utiliserait un carré de cinq lettres sur cinq composant un alphabet pour le cryptage et le décriptage.

   C O D E S
   A B F G H
   I K L M N
   P Q R T U
   V W X Y Z

Chaque lettre de l'alphabet apparaît une fois. Le I représente aussi le J. 
Le mot clé choisi arbitrairement, "CODES" vient en premier, ensuite le
reste de l'alphabet, en évitant les lettres déjà utilisées.

Pour crypter, séparez le message texte en groupes de deux lettres. Si un groupe
a deux lettres identiques, supprimez la seconde et formez un nouveau groupe.
Si il reste une seule lettre à la fin, insérez le caractère "null", typiquement
un "X".

THIS IS A TOP SECRET MESSAGE

TH IS IS AT OP SE CR ET ME SA GE

Pour chaque groupe, il existe trois possibilités.
-------------------------------------------------
1) Les deux lettres sont sur la même ligne du carré
   Pour chaque lettre, substituez celle immédiatement à droite sur la ligne. Si 
   nécessaire, retournez au début de la ligne.
ou

2) Les deux lettres sont dans la même colonne du carré
   Pour chaque lettre, substituez celle immédiatement en dessous sur cette colonne. 
   Si nécessaire, retournez en haut de la colonne.

ou

3) Les deux lettres sont aux coins d'un rectangle à l'intérieur du carré.
   Pour chaque lettre, substituez celle à l'autre coin du rectangle se trouvant
   sur la même ligne.


Le groupe "TH" fait partie du cas #3.
G H
M N
T U           (Rectangle avec "T" et "H" aux coins)

T --> U
H --> G


Le groupe "SE" fait partie du cas #1.
C O D E S     (Ligne contenant "S" et "E")

S --> C  (on retourne au début de la ligne)
E --> S

=========================================================================

Pour décrypter un texte, inversez la procédure ci-dessus pour #1 et #2
(déplacez-vous dans la direction opposée pour la substitution). Pour le cas #3,
prenez juste les deux coins restants du rectangle.


Le travail classique d'Helen Fouche Gaines, "Elementary Cryptoanalysis" (1939),
donne les étapes détaillées sur le cryptage Playfair et ses méthodes de
résolution.

Ce script aura trois sections principales

  1. Génération du << carré de clé >>, basé sur un mot-clé entré par l'utilisateur.

  2. Cryptage d'un message << texte >>.

  3. Décryptage du texte crypté.

Ce script utilisera de façon poussée les tableaux et les fonctions.

--

Merci de ne pas envoyer à l'auteur vos solutions pour ces exercices. Il existe de bien meilleures façons de l'impressionner avec votre intelligence, comme par exemple l'envoi de corrections de bogues et des suggestions pour améliorer ce livre.

>

bash$ grep -n Linux osinfo.txt
2:This is a file containing information about Linux.
 6:The GPL governs the distribution of the Linux operating system.
	      

-v (ou --invert-match) n'affiche pas les correspondances, seulement celles qui ne correspondent pas.
grep motif1 *.txt | grep -v motif2

# Recherche dans "*.txt" de "motif1",
# mais ***pas*** "modif2".	      

-c (--count) affiche le nombre de correspondances trouvées, plutôt que de les afficher.
grep -c txt *.sgml   # (nombre d'occurences de "txt" dans les fichiers "*.sgml")


#   grep -cz .
#            ^ point
# signifie compter (-c) les objets séparés par des zéros (-z) correspondant à "."
# c'est à dire, ceux qui ne sont pas vides (contenant au moins 1 caractère).
# 
printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz .     # 4
printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz '$'   # 5
printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz '^'   # 5
#
printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -c '$'    # 9
# Par défaut, les caractères de fin de ligne (\n) séparent les objets à rechercher. 

# Notez que -z est spécifique à GNU "grep"


# Merci, S.C.

Lorsqu'il est invoqué avec plus d'un fichier cible donné, grep spécifie quel fichier contient les correspondances.

bash$ grep Linux osinfo.txt misc.txt
osinfo.txt:This is a file containing information about Linux.
osinfo.txt:The GPL governs the distribution of the Linux operating system.
misc.txt:The Linux operating system is steadily gaining in popularity.
	      

Astuce

Pour forcer grep à montrer le nom du fichier pendant la recherche d'un fichier cible, donnez /dev/null comme deuxième fichier.

bash$ grep Linux osinfo.txt /dev/null
osinfo.txt:This is a file containing information about Linux.
 osinfo.txt:The GPL governs the distribution of the Linux operating system.
	      

S'il y a une correspondance trouvée, grep retourne un code de sortie de 0, ce qui le rend utile comme test conditionnel dans un script, en particulier en combinaison avec l'option -q pour supprimer la sortie.
SUCCES=0                      # si la recherche avec grep est fructueuse
mot=Linux
nomfichier=donnees.fichier

grep -q "$mot" "$nomfichier"    # -q supprime l'affichage vers stdout

if [ $? -eq $SUCCES ]
then
  echo "$mot trouvé dans $nomfichier"
else
  echo "$mot introuvable dans $nomfichier"
fi

L'Exemple 30-6 démontre comment utiliser grep pour chercher un mot dans un fichier de traces.

Exemple 12-12. Emuler << grep >> dans un script

#!/bin/bash
# grp.sh: Une réimplémentation brute de 'grep'.

E_MAUVAISARGS=65

if [ -z "$1" ]    # Vérification standard des arguments de ligne de commande.
then
  echo "Usage: `basename $0` motif"
  exit $E_MAUVAISARGS
fi  

echo

for fichier in *          # Parcourt tous les fichiers dans $PWD.
do
  sortie=$(sed -n /"$1"/p $fichier)  # Substitution de commande.

  if [ ! -z "$sortie" ]   # Que se passe t-il si "$sortie" n'est pas quotés ?
  then
    echo -n "$fichier: "
    echo $sortie
  fi     #  sed -ne "/$1/s|^|${fichier}: |p"  est l'équivalent de dessus.

  echo
done  

echo

exit 0

# Exercices:
# ---------
# 1) Ajoutez des sauts de lignes à la sortie,
#    s'il y a plus d'une correspondance dans n'importe quel fichier donné.
# 2) Ajoutez des nouvelles possibilités.

Note

egrep est comme grep -E. Elle utilise un jeu d'expressions régulières légèrement différent et étendu, ce qui peut rendre une recherche plus flexible.

fgrep est comme grep -F. Elle recherche une chaîne littérale (pas d'expressions régulières), ce qui accélère les choses.

agrep étend les possibilités de grep à une recherche approximative. La chaîne peut différer d'un nombre spécifié de caractères des résultats de recherches. Cette commande ne fait pas partie des distributions Linux.

Astuce

Pour chercher dans des fichiers compressés, utilisez zgrep, zegrep ou zfgrep. Ces commandes marchent aussi avec des fichiers non compressés, bien que plus lentement qu'un simple grep, egrep, fgrep. C'est pratique pour chercher dans divers fichiers, compressés ou non.

Pour chercher dans des fichiers compressés avec bzip, utilisez bzgrep.

look

La commande look fonctionne comme grep mais fait une recherche basée sur un << dictionnaire >>, une liste de mots triés. Par défaut, look cherche une correspondance dans /usr/dict/words mais un autre dictionnaire peut être utilisé.

Exemple 12-13. Chercher les mots dans une liste pour tester leur validité

#!/bin/bash
#  lookup: Fait une recherche basée sur un dictionnaire sur chaque mot d'un
#+ fichier de données.

fichier=mots.donnees  #  Le fichier de données a partir duquel on lit les mots à
                      #+ tester.

echo

while [ "$mot" != end ]  # Le dernier mot du fichier de données.
do
  read mot      #  Depuis le fichier de données, à cause de la redirection à la
                #+ fin de la boucle.
  look $mot > /dev/null  #  Nous ne voulons pas afficher les lignes dans le
                         #+ dictionnaire.
  lookup=$?      # Code de sortie de 'look'.

  if [ "$lookup" -eq 0 ]
  then
    echo "\"$mot\" est valide."
  else
    echo "\"$mot\" est invalide."
  fi  

done <"$fichier"    #  Redirige stdin vers $fichier, donc les "lectures"
                    #+ commencent à partir d'ici.

echo

exit 0

# -----------------------------------------------------------------------------
# Le code ci-dessous ne s'exécutera pas au cause de la commande exit au dessus


# Stephane Chazelas propose aussi ce qui suit, une alternative plus concise :

while read mot && [[ $mot != end ]]
do if look "$mot" > /dev/null
   then echo "\"$mot\" est valide."
   else echo "\"$mot\" est invalide."
   fi
done <"$fichier"

exit 0
sed, awk

Langages de script créés spécialement pour analyser les fichiers texte et les sorties de commandes. Peuvent être intégrés seuls ou emsembles dans des tubes et des scripts shell.

sed

<< Editeur de flux >> non interactif, permettant d'utiliser plusieurs commandes ex dans un mode batch. C'est souvent utile dans des scripts shell.

awk

Extracteur et formatteur de fichiers programmables, bon pour la manipulation ou l'extraction de champ (colonnes) dans des fichiers textes structurés. Sa syntaxe est similaire à C.

wc

wc (word count) donne le nombre de mots d'un fichier ou d'un flux:
bash $ wc /usr/doc/sed-3.02/README
20     127     838 /usr/doc/sed-3.02/README
[20 lignes  127 mots  838 caractère]

wc -w donne seulement le nombre de mots.

wc -l donne seulement le nombre de lignes.

wc -c donne le nombre de caractères.

wc -L donne la taille de la ligne la plus longue.

Utiliser wc pour connaître le nombre de fichiers .txt dans le répertoire courant :
$ ls *.txt | wc -l
#  Cela ne fonctionnera que si aucun fichier "*.txt" ont un saut de ligne dans
#+ leur noms.

# D'autres moyens de faire ça:
#      find . -maxdepth 1 -name \*.txt -print0 | grep -cz .
#      (shopt -s nullglob; set -- *.txt; echo $#)

# Merci, S.C.

Utiliser wc pour compter la taille de tous les fichiers dont le nom commence avec les lettres d à h
bash$ wc [d-h]* | grep total | awk '{print $3}'
71832
	      

Utiliser wc pour compter le nombre de fois que << Linux >> apparaît dans ce document.
bash$ grep Linux abs-book.sgml | wc -l
50
	      

Voir aussi Exemple 12-30 et Exemple 16-7.

Certaines commandes incluent quelques fonctionnalité de wc comme options.
... | grep foo | wc -l
# Cette construction fréquemment utilisée peut être plus concise.

... | grep -c foo
# Utiliser l'option "-c" (or "--count") de grep à la place.

# Merci, S.C.

tr

Filtre de traduction de caractères.

Attention

Utilisez les guillemets et/ou les parenthèses, si besoin est. Les guillemets empêchent le shell de réinterpréter les caractères spéciaux dans les séquences de commande de tr. Les parenthèses devraient être mises entre guillemets pour empêcher leur expansion par le shell.

tr "A-Z" "*" < fichier ou tr A-Z \* < fichier remplacent toutes les majuscules de fichier par des astérisques (le résultat est écrit dans stdout). Sur certains systèmes, ça peut ne pas fonctionner. Cependant tr A-Z '[**]' fonctionnera.

-d efface un intervalle de caractères.
echo "abcdef"                 # abcdef
echo "abcdef" | tr -d b-d     # aef


tr -d 0-9 < fichierbidon
# Efface tous les chiffres du fichier "fichierbidon".

--squeeze-repeats (ou -s) efface tout sauf la première occurence d'une chaîne de caractères. Cette option est utile pour supprimer les espaces blancs superflus.
bash$ echo "XXXXX" | tr --squeeze-repeats 'X'
X

-c << complement >> inverse l'ensemble des caractères à détecter. Avec cette option, tr n'agit que sur les caractères ne faisant pas parti de l'ensemble spécifiés.

bash$ echo "acfdeb123" | tr -c b-d +
+c+d+b++++

Notez que tr reconnait les ensembles de caractères POSIX. [1]

bash$ echo "abcd2ef1" | tr '[:alpha:]' -
----2--1
	      

Exemple 12-14. toupper: Transforme un fichier en majuscule.

#!/bin/bash
# Met unemajuscule un fichier

E_MAUVAISARGS=65

if [ -z "$1" ]  # Vérification standard des arguments de ligne de commande.
then
  echo "Usage: `basename $0` nomfichier"
  exit $E_MAUVAISARGS
fi  

tr a-z A-Z <"$1"

# Même effet que le programme au dessus, mais utilisant la notation POSIX :
#        tr '[:lower:]' '[:upper:]' <"$1"
# Merci, S.C.

exit 0

Exemple 12-15. lowercase: Change tous les noms de fichier du répertoire courant en minuscule.

#! /bin/bash
#
# Change chaque nom de fichier en minuscules dans le répertoire courant.
#
# Inspiré par un script de John Dubois,
# qui fut traduit en Bash par Chet Ramey,
# et considérablement simplifié par Mendel Cooper, auteur de ce document.


for nomfichier in *             # Scanne tous les fichiers du répertoire.
do
   nomF=`basename $nomfichier`
   n=`echo $nomF | tr A-Z a-z`  # Change le nom en minuscule.
   if [ "$nomF" != "$n" ]       #  Renomme seulement les fichiers qui ne sont
                                #+ pas en minuscules.
   then
     mv $nomF $n
   fi  
done   

exit 0


# Le code en dessous ne s'exécutera pas à cause de la commande exit au dessus
#-----------------------------------------------------------------------------#
# Pour le lancer, effacez la ligne de script ci dessus.

#  Le script suivant ne fonctionnera pas sur les fichiers dont le nom a des
#+ espaces ou des caractères de saut de ligne.

# Stephane Chazelas suggère donc l'alternative suivante :


for nomfichier in *  # Pas nécéssaire d'utiliser basename,
                     # car "*" ne retourne aucun fichier contenant "/".
do n=`echo "$nomfichier/" | tr '[:upper:]' '[:lower:]'`
#                             Jeu de notation POSIX.
#                    Le slash est ajouté, comme ça les saut de lignes ne sont
#                    pas supprimés par la substition de commande.
   # Substitution de variable :
   n=${n%/}          #  Supprime le slash de fin, rajouté au dessus, du nom de
                     #+ fichier.
   [[ $nomfichier == $n ]] || mv "$nomfichier" "$n"
                     # Vérifie si le nom de fichier est déjà en minuscules.
done

exit 0

Exemple 12-16. du: Converti les fichiers text DOS vers UNIX.

#!/bin/bash
# du.sh: Convertisseur de fichier texte DOS vers UNIX.

E_WRONGARGS=65

if [ -z "$1" ]
then
  echo "Usage: `basename $0` fichier-a-convertir"
  exit $E_WRONGARGS
fi

NEWFILENAME=$1.unx

CR='\015'  # Retour charriot.
# En DOS, les lignes se termine par un CR-LF.

tr -d $CR < $1 > $NEWFILENAME
# Efface les caractères CR et écrit le résultat dans un nouveau fichier.

echo "Le fichier texte DOS original est \"$1\"."
echo "Le fichier UNIX converti est \"$NEWFILENAME\"."

exit 0

Exemple 12-17. rot13: rot13, cryptage ultra-faible.

#!/bin/bash
# rot13.sh: L'algorithme classique rot13,
#           cryptage qui pourrait berner un gamin de 3 ans.

# Usage: ./rot13.sh nomfichier
# ou     ./rot13.sh <nomfichier
# ou     ./rot13.sh et fournissez une entrée clavier (stdin)

cat "$@" | tr 'a-zA-Z' 'n-za-mN-ZA-M'   # "a" devient "n", "b" devient "o", etc.
#  La commande 'cat "$@"'
#+ permet la saisie de données depuis soit stdin soit un fichier.

exit 0

Exemple 12-18. Générer des puzzles << Crypto-Citations >>

#!/bin/bash
# crypto-quote.sh: Crypte les citations

# Crypte de célèbre citations par une simple substitution de lettres.
#  Le résultat est similaire aux puzzles "Crypto Quote"
#+ vus sur les pages "Op Ed" du journal Sunday.


key=ETAOINSHRDLUBCFGJMQPVWZYXK
# "key" n'est qu'un alphabet mélangé.
# Changer "key" modifie le cryptage.

# L'instruction 'cat "$@"' prend son entrée soit de stdin, soit de fichiers.
# Si stdin est utilisé, il faut terminer la saisie par un Ctrl-D.
# Sinon, spécifier le nom du fichier en tant que paramètre de la ligne de commande.

cat "$@" | tr "a-z" "A-Z" | tr "A-Z" "$key"
#        |  en majuscule  |     crypte
#  Fonctionne avec n'importe quel type de casse : majuscule, minuscule ou les
#+ deux ensemble.
# Les caractères non-alphabétiques restent inchangés.


# Essayer ce script avec
# "Nothing so needs reforming as other people's habits."
# --Mark Twain
#
# Il en résulte :
# "CFPHRCS QF CIIOQ MINFMBRCS EQ FPHIM GIFGUI'Q HETRPQ."
# --BEML PZERC

# Pour décrypter, utiliser :
# cat "$@" | tr "$key" "A-Z"


#  Ce programme de cryptage bidon peut être cassé par un gosse de 12 ans.

exit 0
fold

Un filtre qui coupe les lignes entrées à partir d'une taille spécifiée. C'est spécialement utile avec l'option -s, qui coupe les lignes à chaque espace (voir Exemple 12-19 et Exemple A-2).

fmt

Un formatteur de fichier tout bête, utilisé en tant que filtre dans un tube pour << couper >> les longues lignes d'un texte.

Exemple 12-19. Affichage d'un fichier formatté.

#!/bin/bash

LARGEUR=40                    # Colonnes de 40 caractères.

b=`ls /usr/local/bin`       # Récupère la liste des fichiers du répertoire

echo $b | fmt -w $LARGEUR

# Aurait pu aussi être fait avec
#  echo $b | fold - -s -w $LARGEUR
 
exit 0

Voir aussi Exemple 12-4.

Astuce

Une puissante alternative à fmt est par de Kamil Toman disponible sur http://www.cs.berkeley.edu/~amc/Par/.

col

Cette commande dont le nom est trompeur supprime les retours chariot inversés d'un flux en entrée. Elle tente aussi de remplacer les espaces blances par des tabulations équivalentes. Le rôle principal de col est de filtrer la sortie de certains utilitaires de manipulation de textes, tels que groff et tbl.

column

Formatteur de colonnes. Ce filtre transforme le texte écrit façon "liste" en un << joli >> tableau par l'insertion de tabulations aux endroits appropriés.

Exemple 12-20. utiliser column pour formatter l'affichage des répertoires

#!/bin/bash
#  Il s'agit d'une légère modification du fichier d'exemple dans la page de
#+ manuel de "column".


(printf "PERMISSIONS LIENS PROPRIETAIRE GROUPE TAILLE MOIS JOUR HH:MM NOM-PROG\n" \
; ls -l | sed 1d) | column -t

#  "sed 1d" efface la première ligne écrite,
#+ qui devrait être "total        N",
#+ où "N" est le nombre total de fichiers trouvés par "ls -l".

# L'option -t de "column" affiche un tableau bien formaté.

exit 0
colrm

Filtre de suppression de colonnes. Ce filtre enlève les colonnes (caractères) d'un fichier et affche le résultat vers stdout. colrm 2 4 < fichier efface le deuxième par bloc de 4 caractères de chaque ligne du fichier fichier.

Avertissement

Si le fichier contient des tabulations ou des caractères non imprimables, ça peut causer des comportements imprévisibles. Dans de tel cas, considérez l'utilisation de expand et unexpand dans un tube précédant colrm.

nl

Filtre de numérotation de lignes. nl fichier affiche fichier sur stdout en insérant un nombre au début de chaque ligne non vide. Si fichier est omit, alors ce filtre travaillera sur stdin.

La sortie de nl est très similaire à cat -n. Cependant, par défaut nl ne liste pas les lignes vides.

Exemple 12-21. nl: Un script d'autonumérotation.

#!/bin/bash

# Ce script s'affiche deux fois sur stdout en numérotant les lignes.

# 'nl' voit ceci comme la ligne 3 car il ne compte pas les lignes blanches.
# 'cat -n' voit la ligne ci-dessus comme étant la ligne 5.

nl `basename $0`

echo; echo  # Maintenant, essayons avec 'cat -n'

cat -n `basename $0`
# La différence est que 'cat -n' numérote les lignes blanches.
# Notez que 'nl -ba' fera de même.

exit 0
pr

Filtre d'impression formatté. Ce filtre paginera des fichiers (ou stdout) en sections utilisables pour des impressions papier ou pour voir à l'écran. Diverses options permettent la manipulation des rangées et des colonnes, le regroupement des lignes, la définition des marges, la numérotation des lignes, l'ajout d'entêtes par page et la fusion de fichiers entre autres choses. La commande pr combine beaucoup des fonctionnalités de nl, paste, fold, column et expand.

pr -o 5 --width=65 fileZZZ | more renvoie un joli affichage paginé à l'écran de fileZZZ avec des marges définies à 5 et 65.

Une option particulèrement utile est -d, forçant le double-espacement (même effet que sed -G).

gettext

Un utilitaire GNU pour localiser et traduire les sorties textes des programmes en langue étrangère. Bien que prévu à l'origine pour les programmes C, gettext trouve aussi son utilité dans des scripts shell. Voir la page info.

iconv

Un utilitaire pour convertir des fichiers en un codage différent (jeu de caractère). Son rôle principal concerne les localisations.

recode

Considérez-le comment une version fantaisie d'iconv, ci-dessus. Ce très souple utilitaire pour la conversion d'un fichier dans un jeu de caractère différent ne fait pas partie d'une installation Linux standard.

TeX, gs

TeX et Postscript sont des langages de balises utilisés pour préparer une impression ou un formattage pour l'affichage vidéo.

TeX est le système "typesetting" élaboré de Donald Knuth. C'est souvent pratique d'écrire un script qui va encapsuler toutes les options et arguments passés à l'un de ces langages.

Ghostscript (gs) est un interpréteur GPL de Postscript .

groff, tbl, eqn

Un autre langage de balises est groff. C'est la version avancée GNU de la commande UNIX roff/troff. Les pages de manuel utilisent groff (voir Exemple A-1).

tbl, utilitaire de création de tableau est considéré comme faisant partie de groff, dans la mesure où sa fonction est de convertir une balise tableau en commandes groff.

Le processeur d'équations eqn fait aussi parti de groff et sa fonction est de convertir une balise d'équation en commandes groff.

lex, yacc

lex, analyseur lexical, produit des programmes pour la détection de motifs. Ca a été remplacé depuis par le non propriétaire flex sur les systèmes Linux.

L'utilitaire yacc crée un analyseur basé sur un ensemble de spécifications. Elle est depuis remplacée par le non propriétaire bison sur les systèmes Linux.

Notes

[1]

Ce n'est vrai que pour la version GNU de tr, pas pour les versions se trouvant dans les systèmes UNIX commerciaux.

BORDER="0" BGCOLOR="#E0E0E0" WIDTH="90%" >
#!/bin/bash
# kill-process.sh

SANSPROCESSUS=2

processus=xxxyyyzzz  # Utilise un processus inexistant.
# Pour les besoins de la démo seulement...
# ... je ne veux pas réellement tuer un processus courant avec ce script.
#
# Si, par exemple, vous voulez utiliser ce script pour vous déconnecter d'Internet,
#     processus=pppd

t=`pidof $processus`       # Trouve le pid (process id) de $processus.
#  Le pid est nécessaire pour 'kill' (vous ne pouvez pas lancer 'kill' sur un nom de
#+ programme).

if [ -z "$t" ]           # Si le processus n'est pas présent, 'pidof' renvoie null.
then
  echo "Le processus $processus n'est pas lancé."
  echo "Rien n'a été tué."
  exit $SANSPROCESSUS
fi  

kill $t              # Vous pouvez avoir besoin d'un 'kill -9' pour les processus fils.

# Une vérification sur l'existence du processus est nécessaire ici.
# Peut-être un autre " t=`pidof $processus` ".


# Ce script entier pourrait être remplacé par
#    kill $(pidof -x processus_name)
# mais cela ne serait pas aussi instructif.

exit 0
fuser

Identifie les processus (par pid) accédant à un fichier donné, à un ensemble de fichiers ou à un répertoire. Pourrait aussi être appelé avec l'option -k, qui tue ces processus. Ceci a des implications intéressantes pour la sécurité du système, spécialement avec des scripts empêchant des utilisateurs non autorisés d'accèder à certains services système.

crond

Plannificateur de programmes d'administration, réalisant des tâches comme le nettoyage et la suppression des journaux système ainsi que la mise à jour de la base de données slocate. C'est la version superutilisateur de at (bien que chaque utilisateur peut avoir son propre fichier crontab modifiable avec la commande crontab). Il s'exécute comme un démon et exécute les entrées plannifiées dans /etc/crontab.

Contrôle de processus et démarrage

init

La commande init est le parent de tous les processus. Appelé à l'étape finale du démarrage, init détermine le niveau d'exécution du système à partir de /etc/inittab. Appellé par son alias telinit, et par root seulement.

telinit

Lien symbolique vers init, c'est un moyen de changer de niveau d'exécution, habituellement utilisé pour la maintenance système ou des réparations en urgence de systèmes de fichiers. Appelé uniquement par root. Cette commande peut être dangereuse - soyez certain de bien la comprendre avant de l'utiliser!

runlevel

Affiche le niveau d'exécution actuel et ancien, c'est-à-dire si le système a été arrêté (niveau 0), était en mode simple-utilisateur (1), en mode multi-utilisateur (2 ou 3), dans X Windows (5) ou en redémarrage (6). Cette commande accède au fichier /var/run/utmp.

halt, shutdown, reboot

Ensemble de commandes pour arrêter le système, habituellement juste avant un arrêt.

Réseau

ifconfig

Configuration fine de l'interface réseau. Il est bien plus utilisé au démarrage lors de la configuration des interfaces, ou à l'arrêt lors d'un redémarrage.
# Code snippets from /etc/rc.d/init.d/network

# ...

# ECheck that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

[ -x /sbin/ifconfig ] || exit 0

# ...

for i in $interfaces ; do
  if ifconfig $i 2>/dev/null | grep -q "UP" >/dev/null 2>&1 ; then
    action "Shutting down interface $i: " ./ifdown $i boot
  fi
# The GNU-specific "-q" option to "grep" means "quiet", i.e., producing no output.
# Redirecting output to /dev/null is therefore not strictly necessary.
       
# ...

echo "Currently active devices:"
echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'`
#                            ^^^^^  should be quoted to prevent globbing.
#  The following also work.
#    echo $(/sbin/ifconfig | awk '/^[a-z]/ { print $1 })'
#    echo $(/sbin/ifconfig | sed -e 's/ .*//')
#  Thanks, S.C., for additional comments.
Voir aussi Exemple 30-6.

route

Affiche des informations sur la façon de modifier la table de routage du noyau.

bash$ route
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
 pm3-67.bozosisp *               255.255.255.255 UH       40 0          0 ppp0
 127.0.0.0       *               255.0.0.0       U        40 0          0 lo
 default         pm3-67.bozosisp 0.0.0.0         UG       40 0          0 ppp0
	      

chkconfig

Vérifie la configuration du réseau. Cette commande affiche et gère les services réseau lancés au démarrage dans le répertoire /etc/rc?.d.

Originellement un port d'IRIX vers Red Hat Linux, chkconfig pourrait ne pas faire partie de l'installation principale des différentes distributions Linux.

bash$ chkconfig --list
atd             0:off   1:off   2:off   3:on    4:on    5:on    6:off
 rwhod           0:off   1:off   2:off   3:off   4:off   5:off   6:off
 ...
	      

tcpdump

<< Reniffleur >> de paquets réseau. C'est un outil pour analyser et corriger le trafic sur un réseau par l'affichage des en-têtes de paquets correspondant à des critères précis.

Affiche le trafic des paquets ip entre l'hôte bozoville et caduceus:
bash$ tcpdump ip host bozoville and caduceus
	      

Bien sûr, la sortie de tcpdump est analysable en utilisant certains utilitaires texte préalablement discutées.

Filesystem

mount

Monte un système de fichier, généralement sur un périphérique externe, tel qu'un lecteur de disquette ou de CDROM. Le fichier /etc/fstab comprend tous les systèmes de fichiers, partitions et périphériques disponibles pouvant être montés manuellement ou automatiquement. Le fichier /etc/mtab affiche les systèmes de fichiers et partitions actuellement montés (en incluant les systèmes virtuels tels que /proc).

mount -a monte tous les systèmes de fichiers et partitions indiqués dans /etc/fstab, à l'exception de ceux disposant de l'option noauto. Au démarrage, un script de /etc/rc.d (rc.sysinit ou un similaire) appelle cette commande pour monter tout ce qui doit l'être.

mount -t iso9660 /dev/cdrom /mnt/cdrom
# Monte le CDROM
mount /mnt/cdrom
# Raccourci, à condition que /mnt/cdrom soit compris dans /etc/fstab

Cette commande versatile peut même monter un fichier ordinaire sur un périphérique bloc et ce fichier agira comme si il était un système de fichiers. Mount accomplit cela en associant le fichier à un périphérique loopback. Une application de ceci est le montage et l'examen d'une image ISO9660 avant qu'elle ne soit gravée sur un CDR. [3]

Exemple 13-5. Vérifier une image

# En tant que root...

mkdir /mnt/cdtest  # Préparez un point de montage, s'il n'existe pas déjà.

mount -r -t iso9660 -o loop cd-image.iso /mnt/cdtest   # Montez l'image.
#                  l'option "-o loop" est équivalent à "losetup /dev/loop0"
cd /mnt/cdtest     # Maintenant, vérifiez l'image
ls -alR            # Listez les fichiers dans cette hiérarchie de répertoires.
                   # Et ainsi de suite.
umount

Démonte un système de fichiers actuellement montés. Avant de supprimer physiquement une disquette ou un CDROM monté au prélable, le périphérique doit être démonté (umount), sinon des corruptions du système de fichiers pourraient survenir.
umount /mnt/cdrom
# Vous pouvez maintenant appuyer sur le bouton d'éjection en toute sécurité.

Note

L'utilitaire automount, s'il est correctement installé, peut monter et démonter des disquettes et des CDROM s'ils sont utilisés ou enlevés. Sur des portables diposant de lecteurs de disquette et CDROM enlevables, ceci peut poser des problèmes.

sync

Force une écriture immédiate de toutes les données mises à jour à partir des tampons vers le disque dur (synchronisation des lecteurs avec les tampons). Bien que cela ne soit pas strictement nécessaire, sync assure à l'administrateur système et à l'utilisateur que les données tout juste modifiées survivront à une soudaine coupure de courant. Aux anciens temps, un sync; sync (deux fois, pour être absolument certain) était une mesure de précaution utile avant un redémarrage du système.

Quelque fois, vous pouvez souhaiter forcer un vidage immédiat des tampons, comme lors de la suppression sécurisée d'un fichier (voir Exemple 12-42) ou lorsque les lumières commencent à clignotter.

losetup

Initialise et configure les périphériques loopback.

Exemple 13-6. Création d'un système de fichiers dans un fichier

TAILLE=1000000  # 1 Mo

head -c $TAILLE < /dev/zero > fichier  # Initialise un fichier de la taille indiquée.
losetup /dev/loop0 fichier             # Le configure en tant que périphérique loopback.
mke2fs /dev/loop0                      # Crée un système de fichiers.
mount -o loop /dev/loop0 /mnt          # Le monte.

# Merci, S.C.
mkswap

Crée une partition de swap ou un fichier. L'aire de swap doit être, du coup, activé avec swapon.

swapon, swapoff

Active/désactive la partition de swap ou le fichier. Ces commandes sont généralement utilisées au démarrage et à l'arrêt.

mke2fs

Crée un système de fichiers ext2 Linux. Cette commande doit être appelée en tant que root.

Exemple 13-7. Ajoute un nouveau disque dur

#!/bin/bash

# Ajouter un deuxième disque dur au système.
# Configuration logiciel. suppose que le matériel est déjà monté.
# A partir d'un article de l'auteur de ce document dans le numéro
# #38 de la "Linux Gazette", http://www.linuxgazette.com.

ROOT_UID=0     # Ce script doit être lancé en tant que root.
E_NOTROOT=67   # Erreur pour les utilisateurs non privilégiés.

if [ "$UID" -ne "$ROOT_UID" ]
then
  echo "Vous devez être root pour utiliser ce script."
  exit $E_NOTROOT
fi  

# A utiliser avec beaucoup de précautions!
# Si quelque chose se passe mal, vous pourriez supprimer votre système de
#+ fichiers complet.


NOUVEAUDISQUE=/dev/hdb    # Suppose que /dev/hdb est disponible. A vérifier!
POINTMONTAGE=/mnt/newdisk # Ou choisissez un autre point de montage.


fdisk $NOUVEAUDISQUE1
mke2fs -cv $NOUVEAUDISQUE1 # Vérifie les mauvais blocs et rend la sortie verbeuse.
#  Note:    /dev/hdb1, *pas* /dev/hdb!
mkdir $POINTMONTAGE
chmod 777 $POINTMONTAGE   # Rend le nouveau disque accessible à tous les utilisateurs.


# Maintenant, testez...
# mount -t ext2 /dev/hdb1 /mnt/newdisk
# Essayez de créer un répertoire.
# Si cela fonctionne, démontez-le et faites.

# Etape finale:
# Ajoutez la ligne suivante dans /etc/fstab.
# /dev/hdb1  /mnt/newdisk  ext2  defaults  1 1

exit 0

Voir aussi Exemple 13-6 et Exemple 29-3.

tune2fs

Configure finement le système de fichiers ext2. Peut être utilisé pour modifier les paramètres du système de fichiers, tels que le nombre maximum de montage. Il doit être utilisé en tant que root.

Avertissement

Cette commande est extrêmement dangereuse. Utilisez-la à vos propres risques, car vous pourriez détruire par inavertance votre système de fichiers.

dumpe2fs

Affiche sur stdout énormément d'informations sur le système de fichiers. Elle doit aussi être appelée en tant que root.

root# dumpe2fs /dev/hda7 | grep 'ount count'
dumpe2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09
 Mount count:              6
 Maximum mount count:      20
hdparm

Liste ou modifie les paramètres des disques durs. Cette commande doit être appelée en tant que root et peut être dangereuse si elle est mal utilisée.

fdisk

Crée ou modifie une table des partitions sur un périphérique de stockage, habituellement un disque dur. Cette commande doit être appelée en tant que root.

Avertissement

Utilisez cette commande avec d'infinies précautions. Si quelque chose se passe mal, vous pouvez détruire un système de fichiers existant.

fsck, e2fsck, debugfs

Ensemble de commandes de vérification, réparation et déboguage des systèmes de fichiers.

fsck: une interface pour vérifier un système de fichiers UNIX (peut appeler d'autres utilitaires). Le type de système de fichiers est par défaut ext2.

e2fsck: vérificateur du système de fichiers ext2.

debugfs: débogueur du système de fichiers ext2. Une des utilités de cette commande versatile, mais dangereuse, est de récupérer (ou plutôt d'essayer de récupérer) des fichiers supprimés. A réserver aux utilisateurs avancés !

Attention

Toutes ce commandes doivent être appelées en tant que root et peuvent endommager, voire détruire, un système de fichiers si elles sont mal utilisées.

badblocks

Vérifie les blocs défectueux (défauts physiques du média) sur un périphérique de stockage. Cette commande trouve son utilité lors du formattage d'un nouveau disque dur ou pour tester l'intégrité du média de sauvegarde. [4] Comme exemple, badblocks /dev/fd0 teste une disquette.

La commande badblocks peut être appelé de façon destructive (écrasement de toutes les données) ou dans un mode lecture-seule non destructif. Si l'utilisateur root est le propriétaire du périphérique à tester, comme c'est le cas habituellement, alors root doit appeler cette commande.

mkbootdisk

Crée une disquette de démarrage pouvant être utilisée pour lancer le système si, par exemple, le MBR (master boot record) est corrumpu. La commande mkbootdisk est en fait un script Bash, écrit par Erik Troan, et disponible dans le répertoire /sbin.

chroot

CHange ROOT directory (modifie le répertoire racine). Habituellement, les commandes sont récupérées à partir de $PATH, depuis la racine /, le répertoire racine par défaut. Cette commande modifie le répertoire racine par un autre répertoire (et modifie aussi le répertoire de travail). Ceci est utile dans des buts de sécurité, par exemple lorsqu'un administrateur système souhaite restreindre certains utilisateurs notamment ceux utilisant telnet, pour sécuriser une partie du système de fichiers (c'est souvent assimilé à confiner un utilisateur invité dans une prison chroot (<< chroot jail >>)). Notez qu'après un chroot, le chemin d'exécution des binaires du système n'est plus valide.

Un chroot /opt ferait que toutes les références à /usr/bin seraient traduites en /opt/usr/bin. De même, chroot /aaa/bbb /bin/ls redirigerait tous les futurs appels à ls en /aaa/bbb comme répertoire de base, plutôt que / comme c'est habituellement le cas. Un alias XX 'chroot /aaa/bbb ls' dans le ~/.bashrc d'un utilisateur restreint réllement la portion du système de fichiers où elle peut lancer des commandes.

La commande chroot est aussi pratique lors du lancement du disquette d'urgence (chroot vers /dev/fd0), ou comme option de lilo lors de la récupération après un crash système. D'autres utilisations incluent l'installation à partir d'un autre système de fichiers (une option rpm) ou le lancement d'un système de fichiers en lecture-seule à partir d'un CDROM. Ne peut s'appeller qu'en tant que root, et à utiliser avec précaution.

Attention

Il pourrait être nécessaire de copier certains fichiers système vers un répertoire compris dans le répertoire de base du chroot, car le $PATH n'est plus fiable.

lockfile

Cet utilitaire fait partie du package procmail (www.procmail.org). Il crée un fichier de verrouillage, un fichier sémaphore qui contrôle l'accès à un fichier, périphérique ou ressource. Le fichier de verrouillage sert en tant qu'indicateur qu'un fichier, périphérique, ressource est utilisé par un processus particulier (<< occupé >>), et ne permet aux autres processus qu'un accès restreint (ou pas d'accès).

Les fichiers de verrouillage sont utilisés par des applications pour protéger les répertoires de courriers électroniques des utilisateurs de modifications simultanées, pour indiquer qu'un port modem est utilisé ou pour montrer qu'une instance de Netscape utilise son cache. Les scripts peuvent vérifier l'existence d'un fichier de verrouillage créé par un certain processus pour vérifier si le processus existe. Notez que si un script essaie de créer un fichier de verrouillage déjà existant, le script a toutes les chances de se terminer précipitamment.

Habituellement, les applications créent et vérifient les fichiers de verrouillage dans le répertoire /var/lock. Un script peut tester la présence d'un fichier de verrouillage de la façon suivante.
nomappl=xyzip
# L'application "xyzip" crée le fichier de verrouillage "/var/lock/xyzip.lock".

if [ -e "/var/lock/$nomappl.lock ]
then
  ...

mknod

Crée des fichiers de périphériques blocs ou caractères (peut être nécessaire lors de l'installation d'un nouveau matériel sur le système).

tmpwatch

Supprime automatiquement les fichiers qui n'ont pas été accédés depuis une certaine période. Appelé habituellement par crond pour supprimer les fichiers journaux.

MAKEDEV

Utilitaire pour la création des fichiers périphériques. Il doit être lancé en tant que root et dans le répertoire /dev.
root# ./MAKEDEV
C'est une espèce de version avancée de mknod.

Backup

dump, restore

La commande dump est un utilitaire élaboré de sauvegarde du système de fichiers, généralement utilisé sur des grosses installations et du réseau. [5] Il lit les partitions brutes du disque et écrit un fichier de sauvegarde dans un format binaire. Les fichiers à sauvegarder peuvent être enregistrés sur un grand nombre de média de stockage incluant les disques et lecteurs de cassettes. La commande restore restaure les sauvegardes faites avec dump.

fdformat

Réalise un formattage bas-niveau sur une disquette.

Ressources système

ulimit

Initialise une limite supérieure sur l'utilisation des ressources système. Habituellement appelé avec l'option -f, qui intialise une limite sur la taille des fichiers (ulimit -f 1000 limite les fichiers à un mégaoctet maximum). L'option -t limite la taille du coredump (ulimit -c 0 élimine les coredumps). Normalement, la valeur de ulimit serait configurée dans /etc/profile et/ou ~/.bash_profile (voir Chapitre 27).

Important

Un emploi judicieux de ulimit peut protéger un système contre l'utilisation des bombes fork.

#!/bin/bash

while 1     #  Boucle sans fin.
do
  $0 &      #  Ce script s'appelle lui-même . . .
            #+ un nombre infini de fois . . .
            #+ jusqu'à ce que le système se gèle à cause d'un manque de ressources.
done        #  C'est le scénario notoire de l'<< apprentissage du sorcier >>.

exit 0      #  Ne sortira pas ici, car ce script ne terminera jamais.

Un ulimit -Hu XX (où XX est la limite du nombre de processus par utilisateur) dans /etc/profile annulerait ce script lorsqu'il dépassera cette limite.

umask

Masque pour la création d'un fichier utilisateur (User MASK). Limite les attributs par défaut d'un fichier pour un utilisateur particulier. Tous les fichiers créés par cet utilisateur prennent les attributs spécifiés avec umask. La valeur (octale) passée à umask définit les droits du fichiers non actifs. Par exemple, umask 022 nous assure que les nouveaux fichiers auront tout au plus le droit 0755 (777 NAND 022). [6] Bien sûr, l'utilisateur peut ensuite modifier les attributs de fichiers spécifiques avec chmod. La pratique habituelle est d'initialiser la valeur de umask dans /etc/profile et/ou ~/.bash_profile (voir Chapitre 27).

rdev

Obtenir des informations sur ou modifier le périphérique racine, l'espace swap ou le mode vidéo. La fonctionnalité de rdev a été principalement repris par lilo, mais rdev reste utile pour configurer un disque ram. C'est une autre commande dangereuse si elle est mal utilisée.

Modules

lsmod

Affiche les modules noyau installés.

bash$ lsmod
Module                  Size  Used by
 autofs                  9456   2 (autoclean)
 opl3                   11376   0
 serial_cs               5456   0 (unused)
 sb                     34752   0
 uart401                 6384   0 [sb]
 sound                  58368   0 [opl3 sb uart401]
 soundlow                 464   0 [sound]
 soundcore               2800   6 [sb sound]
 ds                      6448   2 [serial_cs]
 i82365                 22928   2
 pcmcia_core            45984   0 [serial_cs ds i82365]
	      

Note

Faire un cat /proc/modules donne la même information.

insmod

Force l'installation d'un module du noyau (utilise modprobe à la place, lorsque c'est possible). Doit être appelé en tant que root.

rmmod

Force le déchargement d'un module du noyau. Doit être appelé en tant que root.

modprobe

Chargeur de modules normalement appelé à partir d'un script de démarrage. Doit être appelé en tant que root.

depmod

Crée un fichier de dépendances de module, appelé habituellement à partir d'un script de démarrage.

Divers

env

Lance un programme ou un script avec certaines variables d'environnement initialisées ou modifiées (sans modifier l'environnement système complet). [nomvariable=xxx] permet la modification d'une variable d'environnement nomvariable pour la durée du script. Sans options spécifiées, cette command affiche tous les paramètrages de variables d'environnement.

Note

Dans Bash et d'autres dérivatifs du shell Bourne, il est possible d'initialiser des variables dans un environnement d'une seule commande.
var1=valeur1 var2=valeur2 commandeXXX
# $var1 et $var2 sont uniquement dans l'environnement de 'commandeXXX'.

Astuce

La première ligne d'un script (la ligne << #-! >>) peut utiliser env lorsque le chemin vers le shell ou l'interpréteur est inconnu.
#! /usr/bin/env perl

print "Ce script Perl tournera,\n";
print "même si je ne sais pas où se trouve Perl.\n";

# Bon pour les scripts portables entre les platformes,
# où les binaires Perl pourraient être à l'endroit attendu.
# Merci, S.C.

ldd

Affiche les dépendances des bibliothèques partagées d'un exécutables.

bash$ ldd /bin/ls
libc.so.6 => /lib/libc.so.6 (0x4000c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
strip

Supprime les références symboliques de déboguage à partir d'un exécutable. Ceci réduit sa taille mais rend le déboguage impossible.

Cette commande est fréquente dans un Makefile mais bien plus rare dans un script shell.

nm

Affiche les symboles dans un binaire compilé sur lequel la commande strip n'a pas agi.

rdist

Client distant: synchronise, clone ou sauvegarde un système de fichiers sur un serveur distant.

En utilisant notre connaissance des commandes administratives, examinons un script système. Une des façons les plus courtes et les plus simples de comprendre les scripts est killall, utilisée pour suspendre les processus en cours lors de l'arrêt du système.

Exemple 13-8. killall, à partir de /etc/rc.d/init.d

#!/bin/sh

# --> Commentiares ajoutés par l'auteur de ce document identifiés par "# -->".

# --> Ceci fait partie du paquetage de scripts 'rc'
# --> par Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>

# --> Ce script particulier semble être spécifique à Red Hat
# --> (il pourrait ne pas être présent dans d'autres distributions).

# Arrête tous les services inutiles qui sont en cours d'exécution (ils ne
# devraient pas, donc il s'agit juste d'un test)

for i in /var/lock/subsys/*; do
        # --> Boucle for/in standard, mais comme "do" se trouve sur la même
	# --> ligne, il est nécessaire d'ajouter ";".
	# Vérifie si le script existe.
	[ ! -f $i ] && continue
	# --> C'est une utilisation intelligente d'une "liste et", équivalente
	# --> à if [ ! -f "$i" ]; then continue

	# Obtient  le nom du sous-système.
	subsys=${i#/var/lock/subsys/}
	# --> Correspondance de nom de variable qui, dans ce cas, est le nom du
	# --> fichier. C'est l'équivalent exact à subsys=`basename $i`.
	
	# -->  Il l'obtient du nom du fichier de verrouillage (si il existe un
	# --> fichier de verrou, c'est la preuve que le processus est en cours
	# --> d'exécution).
	# -->  Voir l'entrée "lockfile", ci-dessus.


	# Arrête le sous-système.
	if [ -f /etc/rc.d/init.d/$subsys.init ]; then
	    /etc/rc.d/init.d/$subsys.init stop
	else
	    /etc/rc.d/init.d/$subsys stop
        # --> Suspend les jobs et démons en cours en utilisant la commande
	# --> intégrée 'stop'.
	fi
done

Ce n'était pas si mal. En plus d'un léger travail avec la correspondance de variables, il n'y a rien de plus ici.

Exercice 1. Dans /etc/rc.d/init.d, analyse le script halt. C'est un peu plus long que killall mais similaire dans le concept. Faite une copie de ce script quelque part dans votre répertoire personnel et expérimentez-le ainsi (ne le lancez pas en tant que root). Lancez-le simultanément avec les options -vn (sh -vn nomscript). Ajoutez des commentaires extensifs. Modifiez les commandes << action >> en << echos >>.

Exercice 2. Regardez quelques-uns des scripts les plus complexes dans /etc/rc.d/init.d. Regardez si vous comprenez certaines parties d'entre eux. Suivez la procédure ci-dessus pour les analyser. Pour plus d'indications, vous pouvez aussi examiner le fichier sysvinitfiles dans /usr/share/doc/initscripts-?.??, faisant partie de la documentation d'<< initscripts >>.

Notes

[1]

C'est le cas pour les machines Linux ou Unix disposant d'un système de gestion de quotas disque.

[2]

La commande userdel échouera si l'utilisateur en cours de suppression est connecté à ce moment.

[3]

Pour plus de détails sur la gravure de CDR, voir l'article d'Alex Withers, Créer des CDs, dans le numéro d'octobre 1999 du Linux Journal.

[4]

L'option -c de mke2fs demande aussi une vérification des blocs défectueux.

[5]

Les opérateurs de systèmes Linux simple utilisateur préfèrent généralement quelque chose de plus simple pour leur sauvegarde, comme tar.

[6]

NAND est l'opérateur logique << not-and >>. Son effet est similaire à la soustraction.