Fautivement juste, froidement régulier, splendidement nul
Mortelle perfection ; rien de plus.
--Alfred Lord Tennyson
/dev/zero ... /dev/null
Vous pouvez considérer /dev/null comme un trou noir. L'équivalent le plus proche serait un fichier en écriture seulement. Tout ce qui y est écrit disparaît à jamais. Toute tentative de lecture n'aboutira à rien. Néanmoins, /dev/null peut être très utile à la fois en ligne de commande et dans certains scripts.
Supprimer stdout.
cat $filename >/dev/null # Le contenu de ce fichier ne s'affichera pas sur la sortie stdout.
Supprimer stderr (provenant de l'Exemple 16.3, « Badname élimine dans le répertoire courant les fichiers dont le nom contient des caractères incorrects et des espaces blancs. »).
rm $mauvaisnom 2>/dev/null # Donc les messages d'erreurs [stderr] disparaissent.
Supprimer les sorties à la fois de stdout et stderr.
cat $nom_de_fichier 2>/dev/null >/dev/null # Si "$nom_de_fichier" n'existe pas, aucun message d'erreur ne s'affichera. # Si "$nom_de_fichier" existe bien, le contenu du fichier ne s'affichera pas sur #+ la sortie stdout. # Du coup, aucun affichage ne résultera de la ligne précédente. # # Ceci peut être utile dans certaines situations où le code de retour d'une #+ commande a besoin d'être testée, mais que sa sortie n'est pas souhaitée. # # cat $filename &>/dev/null # fonctionne aussi d'après l'indication de Baris Cicek.
Supprimer le contenu d'un fichier, mais en conservant le fichier lui-même, avec ses droits (provenant de l'Exemple 2.1, « cleanup : Un script pour nettoyer les journaux de trace dans /var/log » et l'Exemple 2.3, « cleanup : Une version améliorée et généralisée des scripts précédents ») :
cat /dev/null > /var/log/messages # : > /var/log/messages a le même résultat mais ne lance pas un nouveau processus. cat /dev/null > /var/log/wtmp
Vider automatiquement le contenu d'un fichier de traces (spécialement intéressant pour s'occuper de ces fichiers dégoutants que sont les « cookies » envoyés par les sites Web commerciaux) :
Exemple 31.1. Cacher le cookie jar
# Navigateur Netscape obsolète. # Les mêmes principes s'appliquent aux derniers navigateurs. if [ -f ~/.netscape/cookies ] # À supprimer s'il existe. then rm -f ~/.netscape/cookies fi ln -s /dev/null ~/.netscape/cookies # Maintenant, tous les cookies se trouvent envoyés dans un trou noir plutôt que # d'être sauvé sur disque.
Comme /dev/null, /dev/zero est un pseudo fichier périphérique qui produit en fait un flux de zéros (des zéros binaires, pas des zéros ASCII). Toute écriture effectuée dans /dev/zero disparaît, et il est plutôt difficile de lire les zéros à partir de là bien que ceci puisse se faire avec od ou un éditeur hexadécimal. L'utilisation principale de /dev/zero est de créer un fichier factice initialisé à une taille prédéterminée pour en faire un fichier de swap temporaire.
Exemple 31.2. Créer un fichier de swap en utilisant /dev/zero
#!/bin/bash # Crée un fichier de swap. # Un fichier swap fournit un espace de stockage pour le cache, #+ ce qui aide à accélérer certaines opérations des systèmes de fichiers. ROOT_UID=0 # Root a l'$UID 0. E_MAUVAIS_UTILISATEUR=65 # Pas root ? FICHIER=/swap TAILLEBLOC=1024 BLOCSMINS=40 SUCCES=0 # Ce script doit être exécuté en tant que root. if [ "$UID" -ne "$ROOT_UID" ] then echo; echo "Vous devez être root pour exécuter ce script."; echo exit $E_MAUVAIS_UTILISATEUR fi blocs=${1:-$BLOCSMINS} # Par défaut à 40 blocs, si rien n'est #+ spécifié sur la ligne de commande. # Ceci est l'équivalent du bloc de commandes ci-dessous. # ------------------------------------------------------ # if [ -n "$1" ] # then # blocs=$1 # else # blocs=$BLOCSMINS # fi # ------------------------------------------------------ if [ "$blocs" -lt $BLOCSMINS ] then blocs=$BLOCSMINS # Doit être au moins long de 40 blocs. fi ###################################################################### echo "Création du fichier swap d'une taille de $blocs blocs (Ko)." dd if=/dev/zero of=$FICHIER bs=$TAILLEBLOC count=$blocs # Vide le fichier. mkswap $FICHIER $blocs # Indique son type : swap. swapon $FICHIER # Active le fichier swap. # Notez que si au moins une de ces commandes échouent, #+ cela posera de sérieux problèmes. ###################################################################### # Exercice : # Ré-écrivez le bloc de code ci-dessus de façon à ce que, #+ si une erreur se produit: # 1) un message d'erreur est envoyé sur stderr, # 2) tous les fichiers temporaires sont nettoyés, # 3) le script sort immédiatement avec un code d'erreur approprié. echo "Fichier swap créé et activé." exit $SUCCES
Une autre application de /dev/zero est de « remplir de zéros » un fichier d'une taille spécifiée pour une raison particulière, telle que monter un système de fichiers sur un périphérique loopback (voir l'Exemple 17.8, « Création d'un système de fichiers dans un fichier ») ou telle que la suppression « sécurisée » d'un fichier (voir l'Exemple 16.60, « Effacer les fichiers de façon sûre »).
Exemple 31.3. Créer un disque ram
#!/bin/bash # ramdisk.sh # Un disque ram ("ramdisk") est un segment de mémoire RAM système agissant #+ comme un système de fichiers. # Son avantage est son accès très rapide (temps de lecture/écriture). # Inconvénients : volatile, perte de données au redémarrage ou à l'arrêt, # moins de RAM disponible pour le système. # # En quoi un disque ram est intéressant ? # Conserver un ensemble de données large, comme une table ou un dictionnaire, #+ sur un disque ram, accélère les recherches de données car l'accès mémoire est #+ bien plus rapide que l'accès disque. E_UTILISATEUR_NON_ROOT=70 # Doit être root. NOM_UTILISATEUR_ROOT=root POINT_MONTAGE=/mnt/ramdisk TAILLE=2000 # 2000 blocs (modifiez comme vous l'entendez) TAILLE_BLOC=1024 # 1K (1024 octets) en taille de bloc PERIPH=/dev/ram0 # Premier périphérique ram nom_utilisateur=`id -nu` if [ "$nom_utilisateur" != "$NOM_UTILISATEUR_ROOT" ] then echo "Vous devez être root pour exécuter \"`basename $0`\"." exit $E_UTILISATEUR_NON_ROOT fi if [ ! -d "$POINT_MONTAGE" ] # Teste si le point de montage est déjà créé, then #+ pour qu'il n'y ait pas d'erreur après mkdir $POINT_MONTAGE #+ plusieurs exécutions de ce script fi ############################################################################## dd if=/dev/zero of=$PERIPH count=$TAILLE bs=$TAILLE_BLOC # Vide le périphérique #+ ram mke2fs $PERIPH # Crée un système de fichiers ext2 dessus. mount $PERIPH $POINT_MONTAGE # Monte le périphérique. chmod 777 $POINT_MONTAGE # Pour que les utilisateurs standards puissent y #+ accéder. # Néanmoins, seul root pourra le démonter. ############################################################################## # Nécessite de tester si les commandes ci-dessus ont réussi. Pourrait poser #+ problème sinon. # Exercice : modifiez ce script pour le rendre plus sûr. echo "\"$POINT_MONTAGE\" est maintenant disponible" # Le disque ram est maintenant accessible pour stocker des fichiers, y compris # par un utilisateur standard. # Attention, le disque ram est volatile et son contenu disparaîtra au prochain #+ redémarrage ou au prochain arrêt. # Copiez tout ce que vous voulez sauvegarder dans un répertoire standard. # Après redémarrage, lancez de nouveau ce script pour initialiser le disque ram. # Remonter /mnt/ramdisk sans les autres étapes ne fonctionnera pas. # Correctement modifié, ce script peut être appelé dans /etc/rc.d/rc.local, #+ pour initialiser le ramdisk automatiquement au lancement. # Cela pourrait être approprié, par exemple, pour un serveur de bases de données. exit 0
En plus de tout ce qui se trouve ci-dessus, /dev/zero est nécessaire pour les binaires UNIX/Linux ELF (acronyme de Executable and Linking Format).