Pourquoi voudriez-vous chat / dev / null sur quelque chose?
Vous ferez cela pour tronquer le contenu d'un fichier tout en conservant l'inode intact. Tous les programmes dont le fichier est ouvert en lecture ou en écriture ne seront pas affectés sauf que la taille du fichier sera remise à zéro.
Une alternative fausse souvent trouvée consiste à supprimer le fichier puis à le recréer:
rm file
touch file
ou similaire:
mv file file.old
gzip file.old
touch file
Le problème est que ces méthodes n’empêchent pas l’ancien fichier d’être conservé par tous les processus où le fichier supprimé est ouvert au moment de la suppression. La raison en est que, sous les systèmes de fichiers Unix, lorsque vous supprimez un fichier, vous ne faites que dissocier son nom (chemin) de son contenu (inode). L'inode est maintenu en vie tant qu'il existe des processus l'ayant ouvert en lecture ou en écriture.
Cela entraîne plusieurs effets négatifs: les journaux écrits après la suppression du fichier sont perdus car il n’existe aucun moyen simple / portable d’ouvrir un fichier supprimé. Tant qu'un processus écrit dans le fichier supprimé, son contenu utilise toujours de l'espace sur le système de fichiers. Cela signifie que si vous supprimez / créez le fichier parce qu'il remplissait votre disque, celui-ci reste rempli. Une façon de résoudre ce dernier problème consiste à redémarrer les processus du consignateur, mais vous pouvez ne pas le faire pour les services critiques et les journaux intermédiaires seraient définitivement perdus. Il existe également des effets secondaires dus au fait que le fichier que vous créez peut ne pas avoir les mêmes autorisations, propriétaire et groupe que celui d'origine. Cela pourrait, par exemple, empêcher un analyseur de journaux de lire le fichier nouvellement créé ou, pire, empêcher le processus de journalisation d'écrire ses propres journaux.
La première méthode permet d’ cat /dev/null > file
atteindre l’objectif correctement, mais malgré une légende urbaine tenace, sa cat /dev/null
partie ne sert absolument à rien. Il ouvre un pseudo fichier qui est vide par conception, il ne lit rien et finit par se fermer. L'utilisation de cette commande est alors un gaspillage de frappes de touche, d'octets, d'appels système et de cycles de processeur et peut être remplacée sans aucune modification fonctionnelle par la commande no-op sans aucun doute plus rapide :
ou même, avec la plupart des shells, par aucune commande.
Laissez-moi essayer une métaphore pour expliquer à quel point l'inutilité cat /dev/null
est inutile . Disons que votre objectif est de vider un verre.
Vous en retirez d'abord tout liquide. C'est suffisant et c'est précisément ce que fait ( > file
) étant donné que les redirections sont toujours traitées en premier.
Ensuite, vous choisissez une bouteille vide ( /dev/null
) et la versez dans le verre vide ( cat
). C'est l'étape inutile
Si vous lisez votre document lié à la fin, vous remarquerez peut-être les commentaires dans cette ligne de la version améliorée du script:
cat / dev / null> wtmp # ':> wtmp' et '> wtmp' ont le même effet.
Ils ont en effet; tant pis a cat /dev/null
été conservé dans le code.
Cela signifie que le code suivant fonctionnera avec tous les shells courants (les deux csh
et leurs sh
familles):
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
et cela fonctionnera avec toutes les coquilles en utilisant la syntaxe Bourne, comme ash
, bash
, ksh
, zsh
et les goûts:
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
Notez cependant qu'avec les anciens shells Bourne pré-POSIX Bourne, aucune de ces commandes, y compris cat /dev/null
, ne tronquera un fichier s'il est écrit ultérieurement par un script shell en cours d'exécution qui lui est ajouté. Au lieu d'un fichier de zéro octet, ce serait un fichier fragmenté dont la taille ne serait pas modifiée. La même chose se produirait si le fichier était écrit par un processus cherchant la position qu’il pensait être la précédente avant l’écriture.
Notez également que certaines solutions alternatives suggérées pour tronquer un fichier ont des défauts.
Les deux suivants ne font tout simplement pas le travail. Le fichier résultant n'est pas vide mais contient une ligne vide. Cela romprait les fichiers journaux comme wtmp
ceux stockant des enregistrements de largeur fixe.
echo > file
echo "" > file
La suivante basée sur une sh
option BSD n'est pas portable, POSIX ne spécifie aucune option autorisée pour l'écho, vous pouvez donc vous retrouver avec un fichier contenant une ligne avec " -n
":
echo -n > file
Celui-ci n'est pas portable non plus en utilisant une sh
séquence d'échappement System V. Certains shells vont créer un fichier contenant une ligne avec " \c
":
echo "\c" > file
Celui-ci utilise une commande conçue pour faire le travail. Le problème n’est truncate
pas portable car cette commande, qui n’a pas été spécifiée par POSIX, est peut-être absente d’un système Unix / Linux.
truncate -s 0
Enfin, voici quelques solutions de rechange portables qui feront le travail correctement: