Note that the order of redirections is significant. For example, the command
ls > dirlist 2>&1
directs both standard output and standard error to the file dirlist,
while the command
ls 2>&1 > dirlist
directs only the standard output to file dirlist, because the
standard error was duplicated from the standard output before the standard
output was redirected to dirlist.
Maintenant, cette dernière partie me prête à confusion. Dans ce cas, toute erreur standard serait imprimée sur le terminal et tout STDOUT irait dans le fichier de liste. C'est ce qui se passerait, mais ce n'est pas ainsi que je comprends le manuel.
Il semble qu'il devrait dire "parce que l'erreur standard a été dupliquée à partir de la sortie standard APRÈS que la sortie standard a été redirigée vers dirlist". Si STDERR a été envoyé à STDOUT avant que STDOUT soit dirigé vers un fichier, le fichier ne contiendrait-il pas STDOUT ET STDERR?
Quelqu'un peut-il clarifier cela pour moi? Est-ce juste une mauvaise compréhension de la lecture de ma part? L'utilisation du mot duplication me semble un peu étrange dans ce contexte. Peut-être que cela me jette.
la source
a = 1; b = a; a = 2
vous vous attendeza == 2 && b == 1
à être vrai. La redirection2>&1
est similaire à l'b = a
affectation - c'est par valeur, pas par référence.2>&1
ne relie pas le descripteur de fichier 2 au descripteur de fichier 1 pour toute l'éternité - il s'agit toujours de 2 descripteurs de fichiers distincts, qui pointent vers le même fichier.Réponses:
La duplication est vraiment la partie importante ici.
Voyons où vont les descripteurs de fichiers avant la redirection. Il s'agit normalement du terminal actuel, par exemple:
Maintenant, si nous appelons
ls -l
sans redirection, les messages de sortie et d'erreur vont à mon terminal sous/dev/pts/1
.Si nous redirigeons d'abord le
STDOUT
vers un fichier (ls -l > dirlist
), cela ressemble à ceci:Lorsque nous redirigeons ensuite vers
STDERR
un doublon duSTDOUT
descripteur de fichier (ls -l > dirlist 2>&1
),STDERR
va vers un doublon de/home/bon/dirlist
:Si nous voulions d' abord rediriger
STDERR
vers un double duSTDOUT
descripteur de fichier de (ls -l 2>&1
):et puis
STDOUT
dans un fichier (ls -l 2>&1 > dirlist
), nous obtiendrions ceci:Ici,
STDERR
va toujours au terminal.Vous voyez, l'ordre dans la page de manuel est correct.
Test de la redirection
Maintenant, vous pouvez le tester vous-même. En utilisant
ls -l /proc/$$/fd/
, vous voyez oùSTDOUT
(avec fd 1) etSTDERR
(avec fd 2), vont pour le processus actuel:Créons un petit script shell qui montre où vos descripteurs de fichiers sont pointés. De cette façon, nous obtenons toujours l'état lors de l'appel
ls
, y compris toute redirection à partir du shell appelant.(Avec CtrlD, vous envoyez une fin de fichier et arrêtez ainsi la
cat
lecture de la commandeSTDIN
.)Maintenant, appelez ce script avec différentes combinaisons de redirection:
Vous pouvez voir que les descripteurs de fichiers 1 (pour
STDOUT
) et 2 (pourSTDERR
) varient. Pour le plaisir, vous pouvez également redirigerSTDIN
et voir le résultat:(Question laissée au lecteur: où pointe le descripteur de fichier 255? ;-))
la source
Non, le manuel est correct.
Si au début 1 pointe vers le terminal, et 2 également vers le terminal, alors:
L'évaluation de la redirection se fera de gauche à droite.
Il évalue
2>&1
donc D'ABORD, et donc PREMIÈRE copie ce que fd pointait1
(c'est-à-dire le descripteur de fichierthe terminal
, généralement / dev / tty) dans fd2
.Donc, à ce point, fd pointe
2
maintenant vers où fd pointait1
(the terminal
)Et ALORS il évalue la
1>somewhere
pièce, et copiera donc le descripteur de fichier desomewhere
dans fd1
(donc à ce point, fd1
pointe maintenant verssomewhere
, et fd2
pointe toujours versthe terminal
)Donc, il imprime en effet 1 dans "quelque part" et 2 dans le terminal, car 2 a été dupliqué de 1 AVANT que 1 n'ait été changé.
L'autre ordre:
redirigera d'abord fd
1
verssomewhere
, puis copiera cette même référence dans fd 2, donc à la fin 2 pointe également verssomewhere
. Mais ils ne sont plus "liés" désormais. Chacun peut toujours être redirigé séparément.ex:
À la fin de celui-ci, fd
1
pointe verssomewhere
, et fd2
est dirigé vers/dev/null
Les noms usuels pour fd
1
sont STDOUT (sortie standard), et le nom usuel pour fd2
est STDERR (erreur standard, car il est couramment utilisé pour afficher les erreurs sans interférer avec STDOUT)la source
cmd 1>somewhere 2>&1 ; exec 2>/dev/null
après l'exec, seulement 2 ont été redirigés vers / dev / null (1 va toujours "quelque part"). J'ai besoin d'aide pour trouver un moyen de dire "ce que 1 pointe vers" au lieu de "le fd 1", cependant ... car c'est aussi déroutant ...Je pense que la partie déroutante ici est la mauvaise compréhension que la redirection de stderr vers stdout connecte réellement les deux flux.
Une idée parfaitement raisonnable, mais ce qui se passe lorsque vous écrivez
2>&1
est stderr prend un coup d'oeil à ce que stdout écrit et écrit au même endroit lui-même. Par conséquent, si vous dites par la suite à stdout d'aller écrire ailleurs, cela n'a aucun effet sur la destination de stderr qui a déjà été déplacée.Je pense que c'est un peu contre-intuitif moi-même mais c'est comme ça que ça fonctionne. Configurez où vous voulez écrire en premier, puis dites à tout le monde "copiez-moi". J'espère que cela clarifie ...
la source
REPRODUCTION...
est important, mais plutôt dans le sens où il est source de beaucoup de confusion . C'est vraiment assez simple. Cette réponse n'est qu'une illustration "radicale".
La réponse acceptée est bonne, mais trop longue et met l'accent sur la "duplication".
Le Q se termine sagement par:
J'utilise la notation bash et je définis les variables "un" et "deux" comme descripteurs de fichiers "1" et "2". L'opérateur de redirection (de sortie)
>
est une affectation=
.&
et$
signifie "valeur" de.Les exemples man bash (avec le "1" par défaut ajouté)
devenir:
et
Et même cela n'est pas automatique pour moi, et pour certains autres, je suppose. La première ligne vous laisse avec
$one
et$two
contenant les deux "dirlist". Bien sûr.La deuxième ligne commence par une affectation inutile. Les deux commencent par définition avec "ATS" (un peu symbolique) comme direction ; aucune valeur n'est modifiée par cette affectation, et avec des variables comme avec des descripteurs de fichiers, rien n'est lié par magie. La variable
two
n'est pas affectée par les éléments suivantsone=dirlist
. Bien sûr que non.Sombody ici (il y a 6 ans) a suggéré "pointer vers" au lieu de "copier" ou "dupliquer", puis s'est rendu compte: ce serait déroutant aussi.
Cette duplication ou sémantique de pointeur n'est même pas nécessaire. C'est peut-être l'esperluette qui a besoin de plus d'attention. Opérateur / jeton / "valeur de".
Si - et seulement si - vous cherchez un moyen d'obtenir un numéro de travail surprenant sur votre console , puis un message "terminé" plus en prime un fichier nommé "2", alors vous allez:
Il se lit naturellement comme " copier" / "dupliquer" 1 à 2, puis les deux ensemble pour annuler . Mais l'idée est fausse, et aussi la syntaxe. (mais pas d'erreur de syntaxe, c'est valide)
La bonne façon de le planifier est de rediriger l'un des deux vers null, puis de rediriger l'AUTRE vers le MÊME endroit:
(le premier "1" peut être laissé de côté)
(OK l'acc. A n'est pas trop long, mais fait trop partie d'une liste - ou: très bonne visualisation, pas si bonne explication)
la source