16. Commandes système et d'administration

Les scripts de démarrage et d'arrêt du répertoire /etc/rc.d illustrent l'utilisation (et l'intérêt) de ces commandes. Elles sont généralement appelées par root et utilisées pour la maintenance du système ou pour des réparation en urgence du système de fichiers. Utilisez-les avec précaution car certaines de ces commandes peuvent endommager votre système en cas de mauvaise utilisation.

Utilisateurs et groupes

users

Affiche tous les utilisateurs connectés. Ceci est l'équivalent approximatif de who -q.

groups

Affiche l'utilisateur actuel et les groupes auxquels il appartient. Ceci correspond à la variable interne $GROUPS mais donne les noms des groupes plutôt que leur identifiants.

bash$ groups
bozita cdrom cdwriter audio xgrp

bash$ echo $GROUPS
501
chown, chgrp

La commande chown modifie le propriétaire d'un ou plusieurs fichiers. Cette commande est utilisée par root pour modifier le propriétaire d'un fichier. Un utilisateur ordinaire peut ne pas pouvoir changer le propriétaire des fichiers, même pas pour ses propres fichiers. [68]

root# chown bozo *.txt

              

La commande chgrp modifie le groupe d'un ou plusieurs fichiers. Vous devez être le propriétaire du fichier ainsi qu'un membre du groupe de destination (ou root) pour réaliser cette opération.

chgrp --recursive dunderheads *.data
#  Ce groupe "dunderheads" sera le propriétaire de tous les fichiers "*.data"
#+ du répertoire $PWD et de ses sous-répertoires (c'est ce que sous-entend le
#+ "recursive").
useradd, userdel

La commande d'administration useradd ajoute un compte utilisateur au système et crée un répertoire personnel pour cet utilisateur particulier si cela est demandé. La commande correspondante userdel supprime le compte de l'utilisateur du système [69] et supprime les fichiers associés.

[Note]

Note

La commande adduser est un synonyme de useradd et est habituellement un lien symbolique vers ce dernier.

usermod

Modifie un compte utilisateur. Les modifications concernent le mot de passe, le groupe d'appartenance, la date d'expiration et d'autres attributs d'un compte utilisateur donné. Avec cette commande, le mot de passe d'un utilisateur peut être verrouillé, ce qui a pour effect de désactiver le compte.

groupmod

Modifie un groupe donné. Le nom du groupe et/ou son numéro d'identifiant est modifiable avec cette commande.

id

La commande id affiche les identifiants réels de l'utilisateur et du groupe pour l'utilisateur associé au processus actuel. C'est la contre-partie des variables internes Bash $UID, $EUID et $GROUPS.

bash$ id
uid=501(bozo) gid=501(bozo) groups=501(bozo),22(cdrom),80(cdwriter),81(audio)

bash$ echo $UID
501
[Note]

Note

La commande id affiche les identifiants actuels seulement s'ils diffèrent des vrais.

Voir aussi l'Exemple 9.5, « Suis-je root ? ».

who

Affiche tous les utilisateurs connectés sur le système.

bash$ who
bozo  tty1     Apr 27 17:45
 bozo  pts/0    Apr 27 17:46
 bozo  pts/1    Apr 27 17:47
 bozo  pts/2    Apr 27 17:49

              

L'option -m donne des informations détaillées sur l'utilisateur actuel. Passer n'importe quels arguments, à condition qu'il en ait deux, à who est l'équivalent de who -m, comme dans who am i ou who The Man.

bash$ who -m
localhost.localdomain!bozo  pts/2    Apr 27 17:49
              

whoami est similaire à who -m mais affiche seulement le nom de l'utilisateur.

bash$ whoami
bozo
              
w

Affiche tous les utilisateurs connectés et les processus leur appartenant. C'est une version étendue de who. La sortie de w peut être envoyée via un tube vers grep pour trouver un utilisateur et/ou un processus spécifique.

bash$ w | grep startx
bozo  tty1     -                 4:22pm  6:41   4.47s  0.45s  startx
logname

Affiche le nom de connexion de l'utilisateur actuel (disponible dans /var/run/utmp). C'est presque l'équivalent de whoami, ci-dessus.

bash$ logname
bozo

bash$ whoami
bozo

Néanmoins...

bash$ su
Password: ......

bash# whoami
root
bash# logname
bozo
[Note]

Note

Bien que logname affiche le nom de l'utilisateur connecté, whoami donne le nom de l'utilisateur attaché au processus actuel. Comme nous l'avons déjà dit, ils ne sont parfois pas identiques.

su

Lance un programme ou un script en substituant l'utilisateur (substitue l'utilisateur). su rjones lance un shell en tant qu'utilisateur rjones. Une commande su sans arguments utilise root par défaut. Voir l'Exemple A.15, « fifo: Faire des sauvegardes journalières, en utilisant des tubes nommés ».

sudo

Lance une commande en tant que root (ou un autre utilisateur). Ceci peut être utilisé dans un script, permettant ainsi à un utilisateur standard de lancer un script.

#!/bin/bash

# Quelques commandes.
sudo cp /root/secretfile /home/bozo/secret
# Quelques autres commandes.

Le fichier /etc/sudoers contient le nom des utilisateurs ayant le droit d'appeller sudo.

passwd

Initialise ou modifie le mot de passe d'un utilisateur.

passwd peut être utilisé dans un script mais ne devrait probablement pas l'être.

Exemple 16.1. Configurer un nouveau mot de passe

#!/bin/bash
#  setnew-password.sh : Pour des raisons de démonstration seulement.
#                       Exécuter ce script n'est pas une bonne idée.
#  Ce script doit être exécuté en tant que root.

UID_ROOT=0                  # Root possède l' $UID 0.
E_MAUVAIS_UTILISATEUR=65    # Pas root ?

E_UTILISATEUR_INEXISTANT=70
SUCCES=0


if [ "$UID" -ne "$UID_ROOT" ]
then
  echo; echo "Seul root peut exécuter ce script."; echo
  exit $E_MAUVAIS_UTILISATEUR
else
  echo
  echo "Vous devriez en savoir plus pour exécuter ce script, root."
  echo "Même les utilisateurs root ont le blues... "
  echo
fi  


utilisateur=bozo
NOUVEAU_MOTDEPASSE=security_violation

# Vérifie si bozo vit ici.
grep -q "$utilisateur" /etc/passwd
if [ $? -ne $SUCCES ]
then
  echo "L'utilisateur $utilisateur n'existe pas."
  echo "Le mot de passe n'a pas été modifié."
  exit $E_UTILISATEUR_INEXISTANT
fi  

echo "$NOUVEAU_MOTDEPASSE" | passwd --stdin "$utilisateur"
#  L'option '--stdin' de 'passwd' permet
#+ d'obtenir un nouveau mot de passe à partir de stdin (ou d'un tube).

echo; echo "Le mot de passe de l'utilisateur $utilisateur a été changé !"

# Utiliser la commande 'passwd' dans un script est dangereux.

exit 0

Les options -l, -u et -d de la commande passwd permettent de verrouiller, déverrouiller et supprimer le mot de passe d'un utilisateur. Seul root peut utiliser ces options.

ac

Affiche le temps de connexion des utilisateurs actuellement connectés à partir des informations lues dans /var/log/wtmp. Il fait partie des utilitaires de mesure GNU.

bash$ ac
        total       68.08
last

Affiche les derniers (last en anglais) utilisateurs connectés suivant les informations disponibles dans /var/log/wtmp. Cette commande peut aussi afficher les connexions distantes.

Par exemple, pour afficher les dernières fois où le système a redémarré :

bash$ last reboot
reboot   system boot  2.6.9-1.667      Fri Feb  4 18:18          (00:02)
reboot   system boot  2.6.9-1.667      Fri Feb  4 15:20          (01:27)
reboot   system boot  2.6.9-1.667      Fri Feb  4 12:56          (00:49)
reboot   system boot  2.6.9-1.667      Thu Feb  3 21:08          (02:17)
...

wtmp begins Tue Feb  1 12:50:09 2005
newgrp

Modifie l'identifiant du groupe de l'utilisateur sans se déconnecter. Ceci permet l'accès aux fichiers du nouveau groupe. Comme les utilisateurs peuvent être membres de plusieurs groupes simultanément, cette commande a peu d'utilité.

[Note]

Note

Kurt Glaesemann indique que la commande pourrait s'avérer utile pour configurer les droits du groupe par défaut pour les fichiers écrit par un utilisateur. Néanmoins, la commande chgrp pourrait être plus efficace pour cela.

Terminaux

tty

Affiche le nom du terminal de l'utilisateur actuel. Notez que chaque fenêtre xterm compte comme un terminal séparé.

bash$ tty
/dev/pts/1
stty

Affiche et/ou modifie les paramétrages du terminal. Cette commande complexe, utilisée dans un script, peut contrôler le comportement du terminal et la façon dont il affiche des caractères. Voir la page info et l'étudier en profondeur.

Exemple 16.2. Configurer un caractère d'effacement

#!/bin/bash
# erase.sh : Utilisation de "stty" pour initialiser un caractère d'effacement
# lors de la lecture de l'entrée standard.

echo -n "Quel est ton nom? "
read nom                       #  Essayez la touche Backspace
                               #+ pour effacer quelques caractères.
                               #  Problèmes ?
echo "Votre nom est $nom."

stty erase '#'                 # Initialisation de la "dièse" (#) comme
                               # caractère d'effacement.
echo -n "Quel est ton nom ? "
read nom                       # Utilisez # pour effacer le dernier caractère
                               # saisi.
echo "Votre nom est $nom."

# Attention : même après la sortie du script, la nouvelle clé reste initialisée.


exit 0

# Même après la sortie du script, la nouvelle clé reste initialisée.
# Exercice : Comment réinitialiser le caractère d'échappement à sa valeur par défaut ?

Exemple 16.3. Mot de passe secret : Désactiver l'écho du terminal

#!/bin/bash
# secret-pw.sh : mot de passe secret

echo
echo -n "Entrez le mot de passe "
read mot_de_passe
echo "Le mot de passe est $mot_de_passe"
echo -n "Si quelqu'un a regardé par dessus votre épaule, "
echo "votre mot de passe pourrait avoir été compromis."

echo && echo  # Deux retours chariot dans une "liste ET".


stty -echo    # Supprime l'echo sur l'écran.

echo -n "Entrez de nouveau le mot de passe "
read mot_de_passe
echo
echo "Le mot de passe est $mot_de_passe"
echo

stty echo     # Restaure l'echo de l'écran.

exit 0

#  Faites un 'info stty'
#+ pour plus d'informations sur cette commande utile mais complexe.

Une utilisation originale de stty concerne la détection de l'appui d'une touche (sans appuyer sur ENTER).

Exemple 16.4. Détection de l'appui sur une touche

#!/bin/bash
# keypress.sh : Détecte un appui sur une touche ("hot keys").

echo

ancienne_config_tty=$(stty -g)   # Sauvegarde de l'ancienne configuration (pourquoi ?).
stty -icanon
Appui_touche=$(head -c1)         # ou $(dd bs=1 count=1 2> /dev/null)
                                 # sur les systèmes non-GNU

echo
echo "La touche est \""$Appui_touche"\"."
echo

stty "$ancienne_config_tty"      # Restaure l'ancienne configuration.

# Merci, Stephane Chazelas.

exit 0

Voir aussi l'Exemple 9.3, « Encore une fois, saisie avec délai ».

setterm

Initialise certains attributs du terminal. Cette commande écrit sur la sortie (stdout) de son terminal une chaîne modifiant le comportement de ce terminal.

bash$ setterm -cursor off
bash$
              

La commande setterm peut être utilisé dans un script pour modifier l'apparence du texte écrit sur stdout bien qu'il existe certainement de meilleurs outils dans ce but.

setterm -bold on
echo bold bonjour

setterm -bold off
echo normal bonjour
tset

Affiche ou initialise les paramétrages du terminal. C'est une version stty comprenant moins de fonctionnalités.

bash$ tset -r
Terminal type is xterm-xfree86.
 Kill is control-U (^U).
 Interrupt is control-C (^C).
              
setserial

Initialise ou affiche les paramètres du port série. Cette commande doit être exécutée par l'utilisateur root et est habituellement utilisée dans un script de configuration du système.

# From /etc/pcmcia/serial script :

IRQ=`setserial /dev/$DEVICE | sed -e 's/.*IRQ: //'`
setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ
getty, agetty

Le processus d'initialisation d'un terminal utilise getty ou agetty pour demander le nom de connexion d'un utilisateur. Ces commandes ne sont pas utilisées dans des scripts shell d'utilisateurs. Leur contre-partie script est stty.

mesg

Active ou désactive les droits d'écriture sur le terminal de l'utilisateur actuel. Désactiver l'accès empêcherait tout utilisateur sur le réseau d'écrire (write en anglais) sur le terminal.

[Astuce]

Astuce

Il peut être très ennuyant de voir apparaître un message pour une commande de pizza au milieu du fichier texte en cours d'édition. Sur un réseau multi-utilisateur, vous pourriez du coup souhaiter désactiver les droits d'écriture sur votre terminal lorsque vous ne voulez pas être dérangé.

wall

C'est un acronyme pour « write all », c'est-à-dire écrire un message à tous les utilisateurs sur tous les terminaux connectés sur le réseau. C'est essentiellement un outil pour l'administrateur système, utile par exemple pour prévenir tout le monde que le système sera bientôt arrêté à cause d'un problème (voir l'Exemple 18.1, « broadcast : envoie des messages à chaque personne connectée »).

bash$ wall Système arrêté pour maintenance dans 5 minutes!
Broadcast message from bozo (pts/1) Sun Jul  8 13:53:27 2001...

 Système arrêté pour maintenance dans 5 minutes!
              
[Note]

Note

Si le droit d'écriture sur un terminal particulier a été désactivé avec mesg, alors wall ne pourra pas envoyer un message à ce terminal.

Informations et statistiques

uname

Affiche les spécifications du système (OS, version du noyau, etc.) sur stdout. Appelé avec l'option -a, donne plus d'informations sur le système (voir l'Exemple 15.5, « Fichier de traces utilisant xargs pour surveiller les journaux système »). L'option -s affiche seulement le type de l'OS.

bash$ uname
Linux

bash$ uname -s
Linux


bash$ uname -a
Linux iron.bozo 2.6.15-1.2054_FC5 #1 Tue Mar 14 15:48:33 EST 2006
 i686 i686 i386 GNU/Linux
arch

Affiche l'architecture du système. Équivalent à uname -m. Voir l'Exemple 10.26, « Utiliser la substitution de commandes pour générer la variable case ».

bash$ arch
i686

bash$ uname -m
i686
lastcomm

Donne une information sur les dernières commandes, disponibles dans le fichier /var/account/pacct. Le nom de la commande et de l'utilisateur peuvent être spécifiés en options. Elle fait partie des utilitaires de comptage GNU.

lastlog

Affiche la dernière connexion de tous les utilisateurs système. Ceci prend comme référence le fichier /var/log/lastlog.

bash$ lastlog
root          tty1                      Fri Dec  7 18:43:21 -0700 2001
 bin                                     **Never logged in**
 daemon                                  **Never logged in**
 ...
 bozo          tty1                      Sat Dec  8 21:14:29 -0700 2001



bash$ lastlog | grep root
root          tty1                      Fri Dec  7 18:43:21 -0700 2001
              
[Attention]

Attention

Cette commande échouera si l'utilisateur l'appellant n'a pas des droits de lecture sur le fichier /var/log/lastlog.

lsof

Affiche les fichiers ouverts. Cette commande affiche une table détaillée de tous les fichiers ouverts et donne de l'information sur leur propriétaire, taille, processus associés et bien plus encore. Bien sûr, lsof pourrait être redirigé avec un tube vers grep et/ou awk pour analyser ce résultat.

bash$ lsof
COMMAND    PID    USER   FD   TYPE     DEVICE    SIZE     NODE NAME
 init         1    root  mem    REG        3,5   30748    30303 /sbin/init
 init         1    root  mem    REG        3,5   73120     8069 /lib/ld-2.1.3.so
 init         1    root  mem    REG        3,5  931668     8075 /lib/libc-2.1.3.so
 cardmgr    213    root  mem    REG        3,5   36956    30357 /sbin/cardmgr
 ...
              

La commande lsof est un outil très utile, mais aussi très complexe. Si vous n'arrivez pas à démonter un système de fichiers et que vous obtenez un message d'erreur indiquant qu'il est en cours d'utilisation, exécuter lsof aide à déterminer les fichiers qui sont toujours ouverts sur ce système de fichiers. L'option -i liste les fichiers socket réseau. Cela peut aider à tracer les intrusions et les tentatives de pénétration.

bash$ lsof -an -i tcp
COMMAND  PID USER  FD  TYPE DEVICE SIZE NODE NAME
 firefox 2330 bozo  32u IPv4   9956       TCP 66.0.118.137:57596->67.112.7.104:http ...
 firefox 2330 bozo  38u IPv4  10535       TCP 66.0.118.137:57708->216.79.48.24:http ...
              
strace

System trace : outil de diagnostic et de débogage traçant les appels système et les signaux. Cette commande et ltrace, qui suit, permettent de diagnostiquer l'échec d'un programme en exécution... un échec qui peut être dû à des bibliothèques manquantes ou à une autre cause proche.

bash$ strace df
execve("/bin/df", ["df"], [/* 45 vars */]) = 0
 uname({sys="Linux", node="bozo.localdomain", ...}) = 0
 brk(0)                                  = 0x804f5e4

 ...
            

C'est l'équivalent Linux de la commande truss sur Solaris.

ltrace

Library trace : outil de diagnostic et de débogage, traçant les appels de bibliothèque réalisé par une commande donnée.

bash$ ltrace df
__libc_start_main(0x804a910, 1, 0xbfb589a4, 0x804fb70, 0x804fb68 <unfinished ...&gt:
 setlocale(6, "")                                 = "en_US.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils")                          = "coreutils"
__cxa_atexit(0x804b650, 0, 0, 0x8052bf0, 0xbfb58908) = 0
getenv("DF_BLOCK_SIZE")                          = NULL

 ...
            
nmap

Network mapper et scanner de port réseau. Cette commande parcourt les ports d'un serveur pour localiser les ports ouverts et les services associés à ces ports. Il peut aussi ramener des informations sur les filtres de paquets et les pares-feu. C'est un important outil de sécurité pour verrouiller un réseau contre les tentatives de pirates.

#!/bin/bash

SERVEUR=$HOST                           # localhost.localdomain (127.0.0.1).
NUMERO_PORT=25                          # Port SMTP.

nmap $SERVEUR | grep -w "$NUMERO_PORT"  # Ce port particulier est-il ouvert ?
#              grep -w établit une correspondance avec des mots entiers
#+             seulement, donc cela permet d'éviter le port 1025 par exemple.

exit 0

# 25/tcp     open        smtp
nc

L'utilitaire nc (netcat) est un ensemble d'outils pour se connecter ou pour écouter à des ports TCP et UDP. Il est utile comme outil de diagnostic et de tests, ainsi que comme composant de scripts simples basés sur les clients et serveurs HTTP.

bash$ nc localhost.localdomain 25
220 localhost.localdomain ESMTP Sendmail 8.13.1/8.13.1;
 Thu, 31 Mar 2005 15:41:35 -0700

Exemple 16.5. Vérification d'identd sur un serveur distant

#! /bin/sh
## Duplique l' « ident-scan » de DaveG en utilisant netcat. Oooh, ça va l'embêter.
## Args: cible port [port port port ...]
## Assemble stdout _et_ stderr.
##
##  Avantages : s'exécute plus lentement qu'ident-scan,
##+ donnant à un inetd distant moins de raison de s'alarmer
##+ et ne prend pour cible que les quelques ports que vous spécifiez.
##  Inconvénients : requiert les arguments du port dans leur version
##+ numérique uniquement, la paresse de l'affichage,
##+ et ne fonctionnera pas pour les r-services lorsqu'ils proviennent
##+ de ports sources supérieurs.
# Auteur du script : Hobbit &lt;hobbit@avian.org&gt;
# Utilisé dans le guide ABS avec sa permission.

# ---------------------------------------------------
E_MAUVAISARGS=65       # A besoin d'au moins deux arguments.
TWO_WINKS=2            # Combien de temps pour dormir.
THREE_WINKS=3
IDPORT=113             # Port d'authentification avec ident.
HASARD1=999
HASARD2=31337
TIMEOUT0=9
TIMEOUT1=8
TIMEOUT2=4
# ---------------------------------------------------

case "${2}" in
  "" ) echo "A besoin d'un hôte et d'au moins un numéro de port." ; exit $E_MAUVAISARGS ;;
esac

# "Ping"uez-les une fois et vérifiez s'ils utilisent identd.
nc -z -w $TIMEOUT0 "$1" $IDPORT || \
{ echo "Oups, $1 n'utilise pas identd." ; exit 0 ; }
#  -z parcourt les démons en écoute.
#     -w $TIMEOUT = Durée de l'essai de connexion.

# Génère un port de base au hasard.
RP=`expr $$ % $HASARD1 + $HASARD2`

TRG="$1"
shift

while test "$1" ; do
  nc -v -w $TIMEOUT1 -p ${RP} "$TRG" ${1} < /dev/null > /dev/null &
  PROC=$!
  sleep $THREE_WINKS
  echo "${1},${RP}" | nc -w $TIMEOUT2 -r "$TRG" $IDPORT 2>&1
  sleep $TWO_WINKS

# Est-ce que ceci ressemble à un mauvais script... ?
# Commentaires de l'auteur du guide ABS : "Ce n'est pas réellement si mauvais,
#+                            en fait, plutôt intelligent."

  kill -HUP $PROC
  RP=`expr ${RP} + 1`
  shift
done

exit $?

#  Notes :
#  ------

#  Essayez de commenter la ligne 30 et d'exécuter ce script
#+ avec "localhost.localdomain 25" comme arguments.

#  Pour plus de scripts d'exemples 'nc' d'Hobbit,
#+ regardez dans la documentation :
#+ le répertoire /usr/share/doc/nc-X.XX/scripts.

Et, bien sûr, il y a le fameux script en une ligne du Dr. Andrew Tridgell dans l'affaire BitKeeper :

echo clone | nc thunk.org 5000 > e2fsprogs.dat
free

Affiche l'utilisation de la mémoire et du cache sous forme de tableau. La sortie de cette commande tend à être analysée avec grep, awk ou Perl. La commande procinfo affiche toute l'information dont dispose la commande free et bien plus encore.

bash$ free
                total       used       free     shared    buffers     cached
   Mem:         30504      28624       1880      15820       1608       16376
   -/+ buffers/cache:      10640      19864
   Swap:        68540       3128      65412

Pour afficher la mémoire RAM inutilisée :

bash$ free | grep Mem | awk '{ print $4 }'
1880
procinfo

Extrait et affiche des informations et des statistiques à partir du pseudo système de fichiers /proc. Cela donne une liste très détaillée.

bash$ procinfo | grep Bootup
Bootup: Wed Mar 21 15:15:50 2001    Load average: 0.04 0.21 0.34 3/47 6829
lsdev

Affiche les périphériques, c'est-à-dire le matériel installé.

bash$ lsdev
Device            DMA   IRQ  I/O Ports
------------------------------------------------
cascade             4     2
dma                          0080-008f
dma1                         0000-001f
dma2                         00c0-00df
fpu                          00f0-00ff
ide0                     14  01f0-01f7 03f6-03f6
...
              
du

Affiche l'utilisation du disque de façon récursive. Par défaut, il prend en compte le répertoire courant.

bash$ du -ach
1.0k    ./wi.sh
1.0k    ./tst.sh
1.0k    ./random.file
6.0k    .
6.0k    total
df

Affiche l'utilisation des systèmes de fichiers sous forme de tableau.

bash$ df
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/hda5               273262     92607    166547  36% /
/dev/hda8               222525    123951     87085  59% /home
/dev/hda7              1408796   1075744    261488  80% /usr
dmesg

Affiche tous les messages de démarrage du système envoyés à stdout. Pratique pour déboguer, pour s'assurer des pilotes de périphériques installés et des interruptions système utilisées. Bien sûr, la sortie de dmesg pourrait être analysée avec grep, sed, ou awk à l'intérieur d'un script.

bash$ dmesg | grep hda
Kernel command line: ro root=/dev/hda2
hda: IBM-DLGA-23080, ATA DISK drive
hda: 6015744 sectors (3080 MB) w/96KiB Cache, CHS=746/128/63
hda: hda1 hda2 hda3 < hda5 hda6 hda7 > hda4
              
stat

Donne des statistiques détaillées, voire verbeuses, sur un fichier donné (voire un répertoire ou un fichier périphérique) ou sur un ensemble de fichiers.

bash$ stat test.cru
  File: "test.cru"
   Size: 49970        Allocated Blocks: 100          Filetype: Regular File
   Mode: (0664/-rw-rw-r--)         Uid: (  501/ bozo)  Gid: (  501/ bozo)
 Device:  3,8   Inode: 18185     Links: 1
 Access: Sat Jun  2 16:40:24 2001
 Modify: Sat Jun  2 16:40:24 2001
 Change: Sat Jun  2 16:40:24 2001
              

Si le fichier cible n'existe pas, stat renvoie un message d'erreur.

bash$ stat fichier-inexistant
nonexistent-file: No such file or directory
              

Dans un script, vous pouvez utiliser stat pour extraire des informations sur les fichiers (et les systèmes de fichiers) et pour configurer des variables suivant le résultat.

#!/bin/bash
# fileinfo2.sh

# D'après une suggestion de Joël Bourquard et...
# http://www.linuxquestions.org/questions/showthread.php?t=410766


FICHIER=testfile.txt
nom=$(stat -c%n "$FICHIER")   # Identique à "$FICHIER" bien sûr.
proprietaire=$(stat -c%U "$FICHIER")
taille=$(stat -c%s "$FICHIER")
#  Certainement plus simple que d'utiliser "ls -l $FICHIER"
#+ et d'analyser la chaîne en retour avec sed.
inode=$(stat -c%i "$FICHIER")
type=$(stat -c%F "$FICHIER")
droits=$(stat -c%A "$FICHIER")

echo "Nom:          $nom"
echo "Propriétaire: $proprietaire"
echo "Taille:       $taille"
echo "Inode:        $inode"
echo "Type:         $type"
echo "Droits:       $droits"

exit 0

sh fileinfo2.sh

Nom:          testfile.txt
Propriétaire: bozo
Taille:       418
Inode:        1730378
Type:         regular file
Droits:       -rw-rw-r--
vmstat

Affiche les statistiques concernant la mémoire virtuelle.

bash$ vmstat
   procs                      memory    swap          io system         cpu
 r  b  w   swpd   free   buff  cache  si  so    bi    bo   in    cs  us  sy id
 0  0  0      0  11040   2636  38952   0   0    33     7  271    88   8   3 89
            
netstat

Affiche des informations et des statistiques sur le réseau, telles que les tables de routage et les connexions actives. Cet utilitaire accède à l'information avec /proc/net (Chapitre 27, /dev et /proc). Voir l'Exemple 27.3, « État de la connexion ».

netstat -r est équivalent à route.

bash$ netstat
Active Internet connections (w/o servers)
 Proto Recv-Q Send-Q Local Address           Foreign Address         State
 Active UNIX domain sockets (w/o servers)
 Proto RefCnt Flags       Type       State         I-Node Path
 unix  11     [ ]         DGRAM                    906    /dev/log
 unix  3      [ ]         STREAM     CONNECTED     4514   /tmp/.X11-unix/X0
 unix  3      [ ]         STREAM     CONNECTED     4513
 . . .
[Note]

Note

La commande netstat -lptu affiche les sockets qui écoutent sur les ports et les processus associés. Ceci est utile pour déterminer si un ordinateur a été compromis.

uptime

Affiche depuis quand le système est lancé ainsi que quelques autres statistiques.

bash$ uptime
10:28pm  up  1:57,  3 users,  load average: 0.17, 0.34, 0.27
[Note]

Note

Une moyenne de charge de 1 ou moins indique que le système gère les processus immédiatement. Une moyenne de charge supérieure à 1 signifie que les processus sont placés dans une queue. Quand la moyenne de charge est supérieure à trois, alors les performances système sont significativement dégradées.

hostname

Affiche le nom d'hôte du système. Cette commande initialise le nom d'hôte dans un script de démarrage /etc/rc.d (/etc/rc.d/rc.sysinit ou similaire). C'est équivalent à uname -n et une contrepartie de la variable interne $HOSTNAME.

bash$ hostname
localhost.localdomain

bash$ echo $HOSTNAME
localhost.localdomain

Similaire à la commande hostname, il existe les commandes domainname, dnsdomainname, nisdomainname et ypdomainname. Utilisez-les pour afficher ou initialiser le DNS système ou le nom de domaine NIS/YP. Différentes options de hostname réalisent aussi ces fonctions.

hostid

Affiche un identifiant numérique (hexadécimal) sur 32 bits pour la machine hôte.

bash$ hostid
7f0100
[Note]

Note

Cette commande récupère prétendument un numéro de série « unique » pour un système particulier. Certaines procédures d'enregistrement d'un produit utilisent ce numéro pour indiquer une licence utilisateur particulière. Malheureusement, hostid ne fait que renvoyer l'adresse réseau en hexadécimal avec quelques octets transposés.

L'adresse réseau d'une machine Linux typique ne se trouvant pas sur un réseau est disponible dans /etc/hosts.

bash$ cat /etc/hosts
127.0.0.1               localhost.localdomain localhost

Il arrive que la transposition de 127.0.0.1 soit 0.127.1.0, ce qui donne en hexadécimal 007f0100, l'équivalent exact de ce que renvoie hostid, ci-dessus. Il existe seulement quelques millions d'autres machines Linux avec ce même hostid.

sar

Appeller sar (System Activity Reporter) donne une indication minutée et très détaillée des statistiques système. L'« ancien » SCO a sorti sar en tant que logiciel OpenSource au mois de juin 1999.

Cette commande ne fait pas partie de la distribution UNIX de base mais peut être obtenue en tant que partie du package des utilitaires sysstat, écrit par Sébastien Godard.

bash$ sar
Linux 2.4.9 (brooks.seringas.fr)     09/26/03

10:30:00          CPU     %user     %nice   %system   %iowait     %idle
10:40:00          all      2.21     10.90     65.48      0.00     21.41
10:50:00          all      3.36      0.00     72.36      0.00     24.28
11:00:00          all      1.12      0.00     80.77      0.00     18.11
Average:          all      2.23      3.63     72.87      0.00     21.27

14:32:30          LINUX RESTART

15:00:00          CPU     %user     %nice   %system   %iowait     %idle
15:10:00          all      8.59      2.40     17.47      0.00     71.54
15:20:00          all      4.07      1.00     11.95      0.00     82.98
15:30:00          all      0.79      2.94      7.56      0.00     88.71
Average:          all      6.33      1.70     14.71      0.00     77.26
           
readelf

Affiche des informations et des statistiques sur un binaire elf indiqué. Cela fait partie du package binutils.

bash$ readelf -h /bin/bash
ELF Header:
   Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
   Class:                             ELF32
   Data:                              2's complement, little endian
   Version:                           1 (current)
   OS/ABI:                            UNIX - System V
   ABI Version:                       0
   Type:                              EXEC (Executable file)
   . . .
size

La commande size [/chemin/vers/binaire] donne les tailles des segments d'un exécutable binaire ou d'un fichier archive. C'est utile principalement pour les programmeurs.

bash$ size /bin/bash
   text    data     bss     dec     hex filename
  495971   22496   17392  535859   82d33 /bin/bash
              

Journal système

logger

Ajoute un message généré par l'utilisateur dans le journal système (/var/log/messages). Vous n'avez pas besoin d'être root pour appeler logger.

logger Instabilité en cours sur la connexion réseau à 23:10, le 21/05.
# Maintenant, lancez un 'tail /var/log/messages'.

En embarquant une commande logger dans un script, il est possible d'écrire des informations de débogage dans /var/log/messages.

logger -t $0 -i Trace sur la ligne "$LINENO".
# L'option "-t" spécifie la balise pour l'entrée du journal.
# L'option "-i" enregistre l'identifiant du processus.

# tail /var/log/message
# ...
# Jul  7 20:48:58 localhost ./test.sh[1712]: Trace sur la ligne 3.
logrotate

Cet utilitaire gère les journaux système, en utilisant une rotation, en les compressant, supprimant, et/ou en les envoyant par courrier électronique. Ceci empêche que /var/log soit rempli d'anciens journaux de traces. Habituellement, cron lance quotidiennement logrotate.

Ajouter une entrée appropriée dans /etc/logrotate.conf rend possible la gestion de journaux personnels ainsi que des journaux système.

[Note]

Note

Stefano Falsetto a créé rottlog, qu'il considère être une version améliorée de logrotate.

Contrôle de job

ps

Statistiques sur les processus (Process Statistics) : affiche les processus en cours d'exécution avec leur propriétaire et identifiant de processus (PID). Celui-ci est habituellement appelé avec les options ax et aux. Le résultat peut être envoyé via un tube à grep ou sed pour repérer un processus spécifique (voir l'Exemple 14.13, « Forcer une déconnexion » et l'Exemple 27.2, « Trouver le processus associé à un PID »).

bash$  ps ax | grep sendmail
295 ?           S      0:00 sendmail: accepting connections on port 25

Pour afficher les processus système en un format d'« arbre » graphique : ps afjx ou ps ax --forest.

pgrep, pkill

Combine la commande ps avec grep ou kill.

bash$ ps a | grep mingetty
2212 tty2     Ss+    0:00 /sbin/mingetty tty2
 2213 tty3     Ss+    0:00 /sbin/mingetty tty3
 2214 tty4     Ss+    0:00 /sbin/mingetty tty4
 2215 tty5     Ss+    0:00 /sbin/mingetty tty5
 2216 tty6     Ss+    0:00 /sbin/mingetty tty6
 4849 pts/2    S+     0:00 grep mingetty


bash$ pgrep mingetty
2212 mingetty
 2213 mingetty
 2214 mingetty
 2215 mingetty
 2216 mingetty
              

Comparer l'action de pkill avec celle de killall.

pstree

Affiche les processus en cours d'exécution avec le format « tree » (arbre). L'option -p affiche les PID ainsi que les noms des processus.

top

Affiche les processus les plus consommateurs de puissances avec un rafraîchissement permanent. L'option -b affiche en mode texte de façon à ce que la sortie puisse être analysée ou tout simplement récupérée à partir d'un script.

bash$ top -b
  8:30pm  up 3 min,  3 users,  load average: 0.49, 0.32, 0.13
 45 processes: 44 sleeping, 1 running, 0 zombie, 0 stopped
 CPU states: 13.6% user,  7.3% system,  0.0% nice, 78.9% idle
 Mem:    78396K av,   65468K used,   12928K free,       0K shrd,    2352K buff
 Swap:  157208K av,       0K used,  157208K free                   37244K cached

   PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
   848 bozo      17   0   996  996   800 R     5.6  1.2   0:00 top
     1 root       8   0   512  512   444 S     0.0  0.6   0:04 init
     2 root       9   0     0    0     0 SW    0.0  0.0   0:00 keventd
   ...
              
nice

Lance un job en tâche de fond avec une priorité modifiée. Les priorités vont de 19 (le plus bas) à -20 (le plus haut). Seul root peut configurer les priorités négatives (les plus hautes). Les commandes en relation sont renice, snice qui modifie la priorité d'un processus en cours d'exécution, et skill qui envoie un signal kill à un ou plusieurs processus.

nohup

Conserve l'exécution d'une commande même si l'utilisateur se déconnecte. La commande s'exécutera en tant que tâche de fond sauf si il est suivi d'un &. Si vous utilisez nohup à l'intérieur d'un script, considérez le fait de le placer avec un wait pour éviter la création d'un processus orphelin ou zombie.

pidof

Identifie l'identifiant du processus (PID) d'un job en cours d'exécution. Comme les commandes de contrôle de job, telles que kill et renice qui agissent sur le PID d'un processus (et non pas son nom), il est parfois nécessaire d'identifier ce PID. La commande pidof est la contrepartie approximative de la variable interne $PPID.

bash$ pidof xclock
880
              

Exemple 16.6. pidof aide à la suppression d'un processus

#!/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` " ou...


# Ce script entier pourrait être remplacé par
#    kill $(pidof -x processus)
# ou
#    killall processus
# 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.

bash$ fuser -u /usr/bin/vim
/usr/bin/vim:         3207e(bozo)



bash$ fuser -u /dev/null
/dev/null:            3009(bozo)  3010(bozo)  3197(bozo)  3199(bozo)
              

Une application importante de fuser arrive lors de l'insertion ou de la suppression physique d'un média de stockage, tel qu'un CDRom ou qu'une clé USB. Quelque fois, lancer un umount échoue avec un message d'erreur device is busy (NdT : le périphérique est occupé). Ceci signifie que des utilisateurs et/ou processus accèdent au périphérique. Une commande fuser -um /dev/device_name fera disparaître le mystère de façon à ce que vous puissiez supprimer les processus en question.

bash$ umount
/mnt/cleusb
umount: /mnt/usbdrive: device is busy



bash$ fuser -um /mnt/cleusb
/mnt/cleusb:        1772c(bozo)

bash$ kill -9 1772
bash$ umount /mnt/usbdrive
              

La commande fuser, appelé avec l'option -n, identifie les processus accèdant à un port. Ceci est particulièrement utile en combinaison avec nmap.

root# nmap localhost.localdomain
PORT     STATE SERVICE
 25/tcp   open  smtp



root# fuser -un tcp 25
25/tcp:               2095(root)

root# ps ax | grep 2095 | grep -v grep
2095 ?        Ss     0:00 sendmail: accepting connections
              
cron

Planificateur 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 planifiées dans /etc/crontab.

[Note]

Note

Quelques versions de Linux utilisent crond, la version de Matthew Dillon pour le cron.

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. Appelé 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.

service

Exécute ou arrête un service système. Les scripts de démarrage compris dans /etc/init.d et /etc/rc.d utilisent cette commande pour exécuter les services au démarrage.

root# /sbin/service iptables stop
Flushing firewall rules:                                   [  OK  ]
Setting chains to policy ACCEPT: filter                    [  OK  ]
Unloading iptables modules:                                [  OK  ]
              

Réseau

ifconfig

Configuration fine de l'interface réseau.

bash$ ifconfig -a
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:700 (700.0 b)  TX bytes:700 (700.0 b)

La commande ifconfig est bien plus utilisée au démarrage lors de la configuration des interfaces ou à l'arrêt lors d'un redémarrage.

# Astuces de code provenant de /etc/rc.d/init.d/network

# ...

# Vérification du réseau.
[ ${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 "Arrêt de l'interface $i: " ./ifdown $i boot
  fi
#  L'option spécifique GNU "-q" de "grep" signifie "silencieux",
#+ c'est-à-dire sans sortie.
#  Du coup, rediriger la sortie vers /dev/null n'est plus nécessaire.

# ...

echo "Périphériques actuellement actifs :"
echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'`
#                            ^^^^^  dévrait être entre guillemets pour éviter un remplacement.
#  Ce qui suit fonctionne aussi.
#    echo $(/sbin/ifconfig | awk '/^[a-z]/ { print $1 })'
#    echo $(/sbin/ifconfig | sed -e 's/ .*//')
#  Merci, S.C., pour les commentaires supplémentaires.

Voir aussi l'Exemple 29.6, « Nettoyage après un Control-C ».

iwconfig

Ceci est un ensemble de commandes pour configurer un réseau sans-fil. C'est l'équivalent sans-fil de ifconfig.

ip

Outil généraliste pour configurer, modifier et analyser les réseaux IP (Internet Protocol) et les périphériques attachées. Cette commande fait partie du paquet iproute2.

bash$ ip link show
1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue 
     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast qlen 1000
     link/ether 00:d0:59:ce:af:da brd ff:ff:ff:ff:ff:ff
 3: sit0: <NOARP> mtu 1480 qdisc noop 
     link/sit 0.0.0.0 brd 0.0.0.0


bash$ ip route list
169.254.0.0/16 dev lo  scope link
              

Ou, dans un script :

#!/bin/bash
# Script de Juan Nicolas Ruiz
# Utilisé avec sa permission.

# Configurer (et stopper) un tunnel GRE.


# --- start-tunnel.sh ---

LOCAL_IP="192.168.1.17"
REMOTE_IP="10.0.5.33"
OTHER_IFACE="192.168.0.100"
REMOTE_NET="192.168.3.0/24"

/sbin/ip tunnel add netb mode gre remote $REMOTE_IP \
  local $LOCAL_IP ttl 255
/sbin/ip addr add $OTHER_IFACE dev netb
/sbin/ip link set netb up
/sbin/ip route add $REMOTE_NET dev netb

exit 0  #############################################

# --- stop-tunnel.sh ---

REMOTE_NET="192.168.3.0/24"

/sbin/ip route del $REMOTE_NET dev netb
/sbin/ip link set netb down
/sbin/ip tunnel del netb

exit 0
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 et du système. 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és.

Systèmes de fichiers

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. ISO 9660 est le standard des systèmes de fichiers pour les CDROM.
mount /mnt/cdrom
# Raccourci, à condition que /mnt/cdrom soit compris dans /etc/fstab

La commande souple mount 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. [70]

Exemple 16.7. 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]

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 disposant de lecteurs de disquette et CDROM enlevables, ceci peut poser des problèmes.

gnome-mount

Les dernières distributions Linux ont rendu obsolètes les commandes mount et umount. Le successeur, pour le montage en ligne de commande des périphériques amovibles, est gnome-mount. Il accepte l'option -d pour monter un périphérique de /dev.

Par exemple, pour monter une clé USB :

bash$ gnome-mount -d /dev/sda1
gnome-mount 0.4


bash$ df
. . .
 /dev/sda1                63584     12034     51550  19% /media/disk
 
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 forcer un vidage immédiat des tampons, comme lors de la suppression sécurisée d'un fichier (voir l'Exemple 15.59, « Effacer les fichiers de façon sûre ») ou lorsque les lumières commencent à clignotter.

losetup

Initialise et configure les périphériques loopback.

Exemple 16.8. Création d'un système de fichiers dans un fichier

TAILLE=1000000  # 1 Mo

head -c $TAILLE < /dev/zero > fichier  # Initialise un fichier à 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. Du coup, l'aire de swap doit être 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 16.9. 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 l'Exemple 16.8, « Création d'un système de fichiers dans un fichier » et l'Exemple 28.3, « Créer un disque ram ».

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]

Avertissement

Cette commande est extrêmement dangereuse. Utilisez-la à vos propres risques, car vous pourriez détruire par inadvertance 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]

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ébogage 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 souple, mais dangereuse, est de récupérer (ou plutôt d'essayer de récupérer) des fichiers supprimés. À réserver aux utilisateurs avancés !

[Attention]

Attention

Toutes ces 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 formatage d'un nouveau disque dur ou pour tester l'intégrité du média de sauvegarde. [71] 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.

lsusb, usbmodules

La commande lsusb affiche tous les bus USB (Universal Serial Bus) et les périphériques qui y sont raccordés.

La commande usbmodules affiche des informations sur les modules du pilote pour les périphériques USB connectés.

bash$ lsusb
Bus 001 Device 001: ID 0000:0000
 Device Descriptor:
   bLength                18
   bDescriptorType         1
   bcdUSB               1.00
   bDeviceClass            9 Hub
   bDeviceSubClass         0
   bDeviceProtocol         0
   bMaxPacketSize0         8
   idVendor           0x0000
   idProduct          0x0000

   . . .
              
lspci

Liste les bus pci présents.

bash$ lspci
00:00.0 Host bridge: Intel Corporation 82845 845
 (Brookdale) Chipset Host Bridge (rev 04)
 00:01.0 PCI bridge: Intel Corporation 82845 845
 (Brookdale) Chipset AGP Bridge (rev 04)
 00:1d.0 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #1) (rev 02)
 00:1d.1 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #2) (rev 02)
 00:1d.2 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #3) (rev 02)
 00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev 42)

   . . .
              
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. L'option --iso est très intéressante car elle permet de demander à mkisofs la création d'une image ISO9660 démarrable et utilisable pour graver un CD.

La commande mkbootdisk est en fait un script Bash, écrit par Erik Troan, et disponible dans le répertoire /sbin.

mkisofs

Crée un système de fichiers ISO9660 convenable pour une image CD.

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]

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 [72] qui contrôle l'accès à un fichier, périphérique ou ressource. Le fichier de verrouillage indique 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).

lockfile /home/bozo/verrous/$0.lock
# Crée un fichier de verrouillage protégé en écriture et préfixé avec le nom du script.

lockfile /home/bozo/lockfiles/${0##*/}.lock
# Une version plus sûre de l'exemple ci-dessus, comme indiqué par E. Choroba.

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. [73] 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   #+ Empêche les autres programmes et scripts
       #  d'accèder aux fichiers/ressources utilisés par xyzip.
  ...
flock

flock est bien moins utile que la commande lockfile. Elle configure un verrou « advisory » sur un fichier puis exécute une commande tant que le verrou est actif. Ceci permet d'empêcher un processus de configurer un verrou sur ce fichier jusqu'à la fin de l'exécution de la commande spécifiée.

flock $0 cat $0 > lockfile__$0
#  Configurer un verrou sur le script où cette ligne apparaît
#+ tout en envoyant le script sur stdout.
[Note]

Note

Contrairement à lockfile, flock ne crée pas automatiquement un fichier de verrouillage.

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). L'outil MAKEDEV a virtuellement toutes les fonctionnalités de mknod et est plus facile à utiliser.

tmpwatch

Supprime automatiquement les fichiers qui n'ont pas été accédés depuis une certaine période. Appelé habituellement par cron 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. C'est en quelque sorte une version avancée de mknod.

tmpwatch

Supprime automatiquement les fichiers qui n'ont pas été utilisés (accédés) depuis une periode de temps spécifiée. Habituellement appelé par cron pour supprimer les vieux journaux de trace.

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. [74] 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 formatage bas-niveau sur une disquette (/dev/fd0*).

Ressources système

ulimit

Initialise une limite supérieure sur l'utilisation des ressources système. Habituellement appelé avec l'option -f qui initialise 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 est configurée dans /etc/profile et/ou ~/.bash_profile (voir l'Annexe G, Fichiers importants).

[Important]

Important

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

#!/bin/bash
# Ce script est inclus dans un but d'illustration seulement.
# Exécutez-le à vos risques et périls -- il BLOQUERA votre système.

while true  #  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'<quote>apprentissage du sorcier</quote>.

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.

quota

Affiche les quotas disque de l'utilisateur ou du groupe.

setquota

Initialise les quotas disque pour un utilisateur ou un groupe à partir de la ligne de commande.

umask

Masque pour des droits de création d'un fichier utilisateur (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). [75] 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 l'Annexe G, Fichiers importants).

Exemple 16.10. Utiliser umask pour cacher un fichier en sortie

#!/bin/bash
# rot13a.sh 
# Identique au script "rot13.sh" mais envoie la sortie dans un fichier sécurisé.

# Usage: ./rot13a.sh nomfichier
# ou     ./rot13a.sh <nomfichier
# ou     ./rot13a.sh et faites une saisie sur le clavier (stdin)

umask 177               #  Masque de création de fichier.
                        #  Les fichiers créés par ce script
                        #+ auront les droits 600.

FICHIERSORTIE=decrypted.txt
  #  Les résultats sont envoyés dans le fichier "decrypted.txt"
  #+ pouvant seulement être lus/écrits par l'utilisateur du script (ou root).

cat "$@" | tr 'a-zA-Z' 'n-za-mN-ZA-M' > $FICHIERSORTIE
#    ^^ Entrée provenant de stdin ou d'un fichier.
                                      # ^^^^^^^^^^^^^^ Sortie redirigée dans un fichier. 

exit 0

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 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]

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.

modinfo

Affiche des informations sur un module chargeable.

bash$ modinfo hid
filename:    /lib/modules/2.4.20-6/kernel/drivers/usb/hid.o
 description: "USB HID support drivers"
 author:      "Andreas Gal, Vojtech Pavlik <vojtech@suse.cz>"
 license:     "GPL"
              

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 commande affiche tous les paramétrages de variables d'environnement. [76]

[Note]

Note

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.

Voire même...

#!/bin/env bash
# Utilise la variable d'environnement $PATH pour trouver l'emplacement de bash.
# Du coup...
# Ce script fonctionnera quand Bash n'est pas à son emplacement habituel, dans /bin.
...
ldd

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

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

Lance une commande plusieurs fois, à des intervalles de temps spécifiés.

Par défaut, il s'agit d'intervalles de deux secondes mais ceci est modifiable avec l'option -n.

watch -n 5 tail /var/log/messages
# Affiche la fin du journal du système, /var/log/messages, toutes les cinq secondes.
[Note]

Note

Malheureusement, envoyer la sortie de watch command dans un tube qui renverra le tout à grep ne fonctionne pas.

strip

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

Cette commande est fréquente dans un Makefile mais est 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.

16.1. Analyser un script système

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, [77] utilisée pour suspendre les processus en cours lors de l'arrêt du système.

Exemple 16.11. killall, à partir de /etc/rc.d/init.d

#!/bin/sh

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

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

# --> Ce script particulier semble être spécifique à Red Hat / FC
# --> (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 de 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.
        # --> Notez que 'stop' est un paramètre de position, pas une commande
        # --> intégrée.
        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, analysez le script halt. C'est un peu plus long que killall mais similaire dans le concept. Faites 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 ».



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

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

[70] 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.

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

[72] Définition : Une sémaphore est un drapeau ou un signal. (L'usage date des chemins de fer où un drapeau coloré, une lanterne ou une sémaphore indiquait si une piste particulière était utilisée et du coup indisponible pour un autre train.) Un processus UNIX peut vérifier la sémaphore appropriée pour déterminer si une ressource particulière est disponible/accessible.

[73] Comme seul root a le droit d'écriture dans le répertoire /var/lock, un script utilisateur ne peut pas initialiser un fichier de verrouillage ici.

[74] 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.

[75] NAND est l'opérateur logique not-and. Son effet est similaire à la soustraction.

[76] 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'.

[77] Le script système killall ne doit pas être confondu avec la commande killall de /usr/bin.