tl; dr
No. >>
est essentiellement "toujours rechercher la fin du fichier" tout en >
maintenant un pointeur sur le dernier emplacement écrit.
Réponse complète
(Remarque: 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 une autre différence. Il 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 redirigez-le vers un fichier avec >
ou >>
(par exemple pv -L 10k /dev/urandom > blob
). Laissez-le fonctionner et changez la taille du fichier (par exemple avec truncate
). Vous verrez que >
son décalage (croissant) se maintient tout >>
en se terminant à la fin.
- Si vous tronquez le fichier à une taille plus petite (la taille peut être nulle)
>
s'en foutra, il écrira à l'offset voulu comme si de rien n'était; juste après que la troncature du décalage dépasse la fin du fichier, le fichier retrouvera son ancienne taille et s'agrandira davantage, les données manquantes seront remplies de zéros (de manière réduite, si possible);
>>
sera ajouté à la nouvelle fin, le fichier passera de sa taille tronquée.
- Si vous agrandissez le fichier
>
s'en foutra, il écrira à l'offset voulu comme si de rien n'était; juste après avoir changé la taille de l'offset se trouvant quelque part dans le fichier, le fichier cessera de croître pendant un certain temps, jusqu'à ce que l'offset atteigne la nouvelle fin, puis le fichier s'agrandira normalement;
>>
sera ajouté à la nouvelle fin, le fichier passera de sa taille agrandie.
Un autre exemple consiste à ajouter (avec un >>
élément séparé ) quelque chose de plus lorsque le processus de génération de données est en cours d'exécution et en écriture dans le fichier. Ceci est similaire à l’agrandissement du fichier.
- Le processus de génération
>
écrit avec le décalage souhaité et écrase les données supplémentaires.
- Le processus de génération avec
>>
sautera les nouvelles données et les ajoutera au-delà (des conditions de concurrence peuvent se produire, les deux flux peuvent être imbriqués, mais aucune donnée ne doit être remplacée).
Exemple
Est-ce important dans la pratique? Il y a cette question :
J'exécute un processus qui produit beaucoup de sortie sur stdout. Tout envoyer dans un fichier [...] Puis-je utiliser un type de programme de rotation des journaux?
Cette réponse dit que la solution est logrotate
avec l' copytruncate
option qui agit comme ceci:
Tronquez le fichier journal d'origine en place après la création d'une copie, au lieu de déplacer l'ancien fichier journal et éventuellement d'en créer un nouveau.
D'après ce que j'ai écrit ci-dessus, la redirection avec >
rendra le journal tronqué volumineux en un rien de temps. La rareté permettra de sauver la journée, aucun espace disque important ne doit être gaspillé. Néanmoins, chaque journal consécutif comportera de plus en plus de zéros non nécessaires.
Mais si vous logrotate
créez des copies sans préserver l’éparpillement, ces zéros non hiérarchiques auront besoin de plus en plus d’espace disque à chaque copie. Je n'ai pas étudié le comportement de l'outil, il est peut-être assez intelligent en cas d'écartement ou de compression à la volée (si la compression est activée). Néanmoins, les zéros ne peuvent que causer des problèmes ou être au mieux neutres; rien de bon en eux.
Dans ce cas, utiliser à la >>
place de >
est nettement préférable, même si le fichier cible est sur le point d'être créé.
Performance
Comme on peut le constater, les deux opérateurs agissent différemment non seulement au début mais aussi plus tard. Cela peut entraîner des différences de performances (subtiles?). Pour l'instant, je n'ai aucun résultat de test significatif pour le confirmer ou le réfuter, mais je pense que vous ne devriez pas automatiquement présumer que leurs performances sont identiques en général.
>>
est essentiellement "toujours chercher à la fin du fichier" tout en>
maintenant un pointeur sur le dernier emplacement écrit. On dirait qu'il pourrait y avoir une différence de performance subtile dans la façon dont ils fonctionnent aussi ...>>
utilise l'O_APPEND
indicateur àopen()
. Et en fait,>
utiliseO_TRUNC
, tandis>>
que non. La combinaison deO_TRUNC | O_APPEND
serait également possible, le langage shell ne fournit tout simplement pas cette fonctionnalité.O_APPEND
avec unlseek()
avant chaquewrite()
serait différent, il y aurait une surcharge d'appels système supplémentaire. (Et bien sûr, cela ne fonctionnerait pas, car un autre processus pourraitwrite()