81 votes

La redirection avec `>>` est-elle équivalente à `>` lorsque le fichier cible n'existe pas encore ?

Considérons un Shell comme Bash ou sh. La différence fondamentale entre > y >> se manifeste dans le cas où le fichier cible existe :

  • > tronque le fichier à une taille nulle, puis écrit ;
  • >> ne tronque pas, il écrit (ajoute) à la fin du fichier.

Si le fichier n'existe pas, il est créé avec une taille nulle, puis écrit. Ceci est vrai pour les deux opérateurs. Il peut sembler que les opérateurs sont équivalents lorsque le fichier cible n'existe pas encore.

Le sont-ils vraiment ?

110voto

Kamil Maciorowski Points 57004

Tl;dr

Non. >> est essentiellement "toujours chercher à la fin du fichier" alors que > maintient un pointeur sur le dernier emplacement écrit.


Réponse complète

(Note : tous mes tests ont été effectués sur Debian GNU/Linux 9).

Une autre différence

Non, ils ne sont pas équivalents. Il y a un autre différence. Elle peut se manifester indépendamment du fait que le fichier cible existait auparavant ou non.

Pour l'observer, exécutez un processus qui génère des données et redirige vers un fichier avec l'option > o >> (par exemple pv -L 10k /dev/urandom > blob ). Laissez-le s'exécuter et modifiez la taille du fichier (par exemple avec truncate ). Vous verrez que > conserve son décalage (croissant) tandis que >> s'ajoute toujours à la fin.

  • Si vous tronquez le fichier à une taille plus petite (il peut être de taille zéro)
    • > ne s'en souciera pas, il écrira à l'offset désiré comme si rien ne s'était passé ; juste après la troncature, l'offset est au-delà de la fin du fichier, ce qui fera que le fichier retrouvera son ancienne taille et grandira encore, les données manquantes seront remplies de zéros (de manière éparse, si possible) ;
    • >> s'ajoutera à la nouvelle fin, le fichier grandira à partir de sa taille tronquée.
  • Si vous agrandissez le fichier
    • > ne s'en souciera pas, il écrira à l'offset désiré comme si rien ne s'était passé ; juste après avoir changé la taille, l'offset se trouve quelque part à l'intérieur du fichier, cela provoquera l'arrêt de la croissance du fichier pendant un moment, jusqu'à ce que l'offset atteigne la nouvelle fin, puis le fichier se développera normalement ;
    • >> s'ajoutera à la nouvelle fin, le fichier grandira à partir de sa taille élargie.

Un autre exemple est d'ajouter (avec un >> ) quelque chose de supplémentaire lorsque le processus de génération de données est en cours d'exécution et écrit dans le fichier. Ceci est similaire à l'agrandissement du fichier.

  • Le processus de génération avec > écrira à son décalage souhaité et écrasera les données supplémentaires éventuellement.
  • Le processus de génération avec >> sautera les nouvelles données et les ajoutera après (une condition de course peut se produire, les deux flux peuvent être entrelacés, mais aucune donnée ne doit être écrasée).

Exemple

Est-ce important dans la pratique ? Il y a cette question :

J'exécute un processus qui produit beaucoup de sorties sur stdout. L'envoi de tout cela vers un fichier [...] Puis-je utiliser une sorte de programme de rotation des journaux ?

Cette réponse dit que la solution est logrotate con copytruncate qui agit comme suit :

Tronquer le fichier journal d'origine en place après avoir créé une copie, au lieu de déplacer l'ancien fichier journal et éventuellement d'en créer un nouveau.

Selon ce que j'ai écrit ci-dessus, la redirection avec > rendra le journal tronqué grand en un rien de temps. L'éparpillement sauvera la journée, aucun espace disque significatif ne devrait être gaspillé. Néanmoins, chaque journal consécutif contiendra de plus en plus de zéros de tête qui ne sont absolument pas nécessaires.

Mais si logrotate crée des copies sans préserver l'espacement, ces zéros de tête auront besoin de plus en plus d'espace disque à chaque fois qu'une copie sera faite. Je n'ai pas étudié le comportement de l'outil, il est peut-être assez intelligent pour préserver la densité ou la compression à la volée (si la compression est activée). Mais les zéros peuvent seulement causer des problèmes ou être neutres au mieux ; rien de bon en eux.

Dans ce cas, l'utilisation de >> au lieu de > est nettement meilleure, même si le fichier cible n'est pas encore créé.


Performance

Comme nous pouvons le constater, les deux opérateurs agissent différemment non seulement au début, mais aussi par la suite. Cela peut entraîner une différence de performance (subtile ?). Pour l'instant, je n'ai pas de résultats de tests significatifs pour confirmer ou infirmer cela, mais je pense que vous ne devriez pas automatiquement supposer que leurs performances sont les mêmes en général.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X