Je commence dans un répertoire vide.
$ touch aFile
$ ls
aFile
Ensuite, j'ai ls
deux arguments, dont l'un n'est pas dans ce répertoire. Je redirige les deux flux de sortie vers un fichier nommé output
. J'utilise >>
afin d'éviter d'écrire simultanément.
$ ls aFile not_exist >>output 2>>output
$ cat output
ls: cannot access 'not_exist': No such file or directory
aFile
Ce qui semble fonctionner. Y a-t-il des dangers à cette approche?
io-redirection
stdout
stderr
exit_status
la source
la source
ls aFile not_exist &>>output
ici? (Remarque, je suppose que vous utilisez bash .)&>>
n'est PAS standard. C'est une syntaxe obsolète et ambiguë qui fonctionne différemment dans différents shells. Je me demande d'où vous tirez vos affaires.ls &>>foo ...
doit être analysé comme deux commandesls &
et>>foo ...
, et c'est ainsi que d'autres shells comme/bin/sh
Ubuntu le analysent. Pour qu'il soit obsolète, vous pouvez regarder ici - bien que je ne prétende pas que ce soit une sorte d'autorité.bash
Cependant, vous pouvez demander aux responsables s'ils considèrent que c'est une bonne idée.Réponses:
Non, ce n'est pas aussi sûr que la norme
>>bar 2>&1
.Quand tu écris
vous ouvrez le
bar
fichier deux fois avecO_APPEND
, créant deux objets de fichier complètement indépendants [1], chacun avec son propre état (pointeur, modes ouverts, etc.).Ceci est très différent de celui
2>&1
qui appelle simplement l'appeldup(2)
système et crée les alias interchangeables stderr et stdout pour le même objet fichier.Maintenant, il y a un problème avec ça:
Vous pouvez généralement compter sur la probabilité du fichier comme
bar
enfoo >>bar 2>&1
cours d' écriture en même temps de deux endroits séparés étant assez faible. Mais par vous,>>bar 2>>bar
vous venez de l'augmenter d'une douzaine d'ordres de grandeur, sans aucune raison.[1] "Open File Descriptions" dans le jargon POSIX.
la source
O_APPEND
c'est une sorte de raté de toute façon - assez onéreux à mettre en œuvre correctement.O_APPEND
, le client récupérera d'abord la "vraie" taille du fichier sur le serveur ("revalidera" l'inode) puis fera la recherche + écriture + mise à jour de l'inode en cache, et seule la dernière partie sera fait sous des verrous, ce qui signifie que la première partie pourrait toujours récupérer une taille périmée à partir du serveur et remplacer la bonne à partir de l'inode local / mis en cache. Même problème aveclseek(SEEK_END)
.Que se passe-t-il lorsque vous le faites
est que
file
sera ouvert pour être ajouté deux fois. Ceci est sûr à faire sur un système de fichiers POSIX. Toute écriture qui arrive au fichier lorsqu'il est ouvert pour l'ajout se produira à la fin du fichier, que les données proviennent du flux de sortie standard ou du flux d'erreur standard.Cela repose sur la prise en charge des opérations d’écriture d’ajout atomique dans le système de fichiers sous-jacent. Certains systèmes de fichiers, tels que NFS, ne prennent pas en charge l'ajout atomique. Voir par exemple la question "Le fichier est-il atomique sous UNIX?" Sur StackOverflow.
En utilisant
fonctionnerait même sur NFS cependant.
Cependant, en utilisant
n'est pas sûr, car le shell tronquera le fichier de sortie (deux fois) et toute écriture qui se produira sur l'un ou l'autre flux écrasera les données déjà écrites par l'autre flux.
Exemple:
La
hello
chaîne est écrite en premier (avec un retour à la ligne de fin), puis la chaîneabc
suivie d'un retour à la ligne est écrite à partir de l'erreur standard, écrasant lehell
. Le résultat est la chaîneabc
avec une nouvelle ligne, suivie de ce qui reste de la premièreecho
sortie, uneo
et une nouvelle ligne.L'échange des deux
echo
autour de la plaie ne produit quehello
dans le fichier de sortie car cette chaîne est écrite en dernier et est plus longue que laabc
chaîne. L'ordre dans lequel les redirections se produisent n'a pas d'importance.Il serait préférable et plus sûr d'utiliser le plus idiomatique
la source
>>
vient), où>>
s'ouvrirait pour l'écriture et chercherait à la fin (je suppose que O_APPEND n'a pas encore été inventé à l'époque). Même sur Solaris 10,/bin/sh -c '(echo a; echo b >&2) >> file 2>> file; cat file'
sortiesb
.sh
ou avec son système de fichiers?>>
faisait à l'origine, il ne s'ouvrait pas avec O_APPEND, il s'ouvrait sans et cherchait jusqu'à la fin. Ce n'est pas vraiment un problème, c'est ce qu'il faisait et a été documenté.Cela dépend de ce que vous voulez réaliser. C'est à vous de décider si vous pouvez avoir des erreurs dans le même fichier que la sortie. Il s'agit simplement d'enregistrer du texte dans un fichier avec les fonctionnalités du shell qui vous permettent de rediriger comme vous le souhaitez. Il n'y a pas de oui ou de non absolu. Comme tout sous Linux, cela peut se faire de plusieurs manières, c'est ma façon de
ls notExistingFile existingFile >> output 2>&1
répondre à la question: en termes de redirection elle-même, oui, c'est parfaitement sûr.la source
>
au lieu de>>
remplacera certains caractères. Ce n'est donc pas seulement que le shell me permet de rediriger, car lorsque je redirige avec>
, le résultat est différent. Il y a donc des nuances avec>
, y en a-t-il avec>>
?>
- écraser.>>
- ajouter