Vous devez généralement cat /dev/null > [something]
effacer le contenu du fichier tout en évitant tout risque d'interruption de l'état du fichier. Le contenu du fichier sera clairement effacé par le cat /dev/null
fichier lui-même - tel qu'il existe et est connu du système de fichiers sur lequel il réside - sera toujours là avec le même numéro d'inode, la même propriété et les mêmes autorisations.
Dans le cas d'un fichier journal, il se peut que le fichier journal lui-même soit marqué «en cours d'utilisation» par un autre processus. Ce faisant, par exemple, rm /var/log/messages && touch /var/log/messages
cela pourrait perturber d'autres processus et provoquer l'étouffement des processus en cours. Signifier qu'un processus qui est en quelque sorte verrouillé sur un numéro d'inode spécifique connecté au fichier /var/log/messages
pourrait soudainement paniquer en disant: «Hé! Qu'est-il arrivé à /var/log/messages
! ”Même si le fichier est toujours là. Sans parler des problèmes potentiels avec la propriété et les autorisations étant recréées de manière incorrecte.
En raison de cette incertitude dans l' utilisation / état d'un fichier de l'utilisation cat /dev/null > [something]
est préféré par les administrateurs système qui veulent effacer un journal , mais ne veulent pas potentiellement interférer avec le fonctionnement des processus déjà existants.
De même, dans le contexte de la page que vous créez un lien avec l'auteur, vous indiquez ce qui suit:
Il n’ya rien d’inhabituel ici, seul un ensemble de commandes qui auraient tout aussi bien pu être invoquées une à une à partir de la ligne de commande de la console ou d’une fenêtre de terminal. Les avantages de placer les commandes dans un script vont bien au-delà du fait de ne pas avoir à les retaper encore et encore.
Donc, le «rien d’inhabituel» que l’auteur mentionne concerne tout le concept de ce script bash spécifique: c’est juste un ensemble de commandes simples qui peuvent tout aussi bien être exécutées à partir de la ligne de commande mais placées dans un fichier texte évitez de les retaper encore et encore.
truncate -s 0
ferait la même chose et serait moins idiomatique. Cependant, les programmeurs shell sont un groupe conservateur et on peut rencontrer des systèmes assez vieux ou assez farfelus pour ne pas avoir cette commande.cat /dev/null > /foo/bar
tronque le fichier;echo "" > /foo/bar
le tronque puis écrit un seul caractère de nouvelle ligne.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:
ou similaire:
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, sacat /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 inutileSi vous lisez votre document lié à la fin, vous remarquerez peut-être les commentaires dans cette ligne de la version améliorée du script:
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 leurssh
familles):et cela fonctionnera avec toutes les coquilles en utilisant la syntaxe Bourne, comme
ash
,bash
,ksh
,zsh
et les goûts: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.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
":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
":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.Enfin, voici quelques solutions de rechange portables qui feront le travail correctement:
Imprimer explicitement une chaîne vide dans le fichier:
Utilisation de la
true
commande strictement équivalente à la commande no-op:
mais plus lisible:la source
csh
implémentations actuelles bien que cela ne soit pas nécessairement documenté. À partir de lacsh
page de manuel Solaris: Null command. This command is interpreted, but performs no action.
. Je n'ai trouvé aucune mention de la même chose dans latcsh
page de manuel ou dans les BSD d'originecsh
, mais cette syntaxe a peut-être toujours fonctionné.cat /dev/null
est de rendre vos intentions explicites./dev/null
d’un moyen efficace d’injecter zéro octet, de toute façon plus fiable que d’utiliser:
ou rien. Dans cette même page, Cyrus répondait qu'il était concis, mais qu'il allait droit au but et qu'il ne comptait aucun vote alors que celui de JakeGould qui contestait le fait qu'ilcat /dev/null
était un non-op (voir nos commentaires) avait déjà au moins quatre votes.>
ou:
n'est pas clair. Je conviens que c'est une honte que des mythes aient été propagés en raison de son utilisation.printf "" > file
fois portable (POSIX) et léger aussi souvent implémenté qu'un shell intégré.C'est un moyen fastidieux de ramener le fichier à une taille nulle.
la source
csh
.: > messages
fonctionne aussi.:
outrue
sont les choix les plus évidents pour les commandes qui n'impriment rien et qui retournent vrai.Pour tronquer un fichier ouvert. Ceci est équivalent et plus compréhensible:
(Ajouté -n pour éviter la nouvelle ligne)
la source
wtmp
cas. Voir ma réponse mise à jour.bash
, il-n
n'est pas garanti qu'il fonctionne dans tous les coques Bourne.