Comment les programmes sortent-ils ailleurs que STDOUT / STDERR? Comment l'éviter?

15

Apparemment, je ne connais pas toutes les destinations de sortie disponibles. Je connais stdout( &1) et stderr( &2). Cependant, après avoir redirigé les deux descripteurs, j'obtiens parfois encore une sortie dans ma console!

L'exemple le plus simple auquel je peux penser est GNU Parallel; Chaque fois que je l'utilise, je vois un avis de citation. Même quand je le fais &2>1 > file, je vois toujours l'avis.

Et la même chose s'applique à emerge: Lorsque je lance emerge et qu'il y a des problèmes, certaines informations ne sont pas imprimées sur stdoutni stdin, car je les redirige et elles continuent de passer.

Je résout principalement ces problèmes en utilisant script, mais je me demande toujours ce qui cause ce problème.

MatthewRock
la source
1
Veuillez fournir un exemple complet .
Kusalananda
quelle coquille? jetez un œil à mywiki.wooledge.org/BashFAQ/055 et stackoverflow.com/questions/876239/…
Sundeep
8
Vous ne les obtiendrez pas tous . Un script peut toujours écrire /dev/tty.
Satō Katsura
1
Quant à GNU parallel: mkdir ~/.parallel; touch ~/.parallel/will-citedésactivera le message ennuyeux. Vous pouvez également rechercher d'autres implémentations de parallel.
Satō Katsura
2
@OleTange Parce que ce n'est pas un problème - je demande pourquoi quelque chose se passe et j'utilise parallelcomme exemple.
MatthewRock

Réponses:

40

La syntaxe que vous avez utilisée est incorrecte.

cmd &2>1 >file

sera divisé en

cmd &
2>1 >file

Cette volonté:

  1. Courir cmd tant que tâche d'arrière-plan sans redirection
  2. Dans un processus séparé (sans commande!) Redirigera stderrvers un fichier appelé littéralement 1et redirigera stdoutversfile

La syntaxe que vous souhaitez est:

cmd >file 2>&1

L'ordre des opérations est important. Cette volonté:

  1. Rediriger stdoutversfile
  2. Rediriger stderrvers &1- c'est- à -dire le même descripteur de fichier questdout

Le résultat est que les deux stderret stdoutseront redirigés vers file.

Dans bash, une syntaxe non standard plus simple (et donc je ne le recommande pas, pour des raisons de portabilité) cmd &> filefait la même chose.

Stephen Harris
la source
Bien, merci. L'autre problème pourrait être /dev/tty, mais j'espère que cela ne se produit pas trop souvent (voire pas du tout).
MatthewRock
5
Si vous avez la atcommande sur votre machine et que vous disposez des privilèges pour l'utiliser, vous pouvez exécuter la commande via at now. Voir la page de manuel pour plus de détails. Cela exécutera la commande via un mécanisme de traitement par lots et le processus n'aura jamais de terminal sur lequel écrire. Mais, en général, je ne m'inquiéterais pas de ce cas de bord. En règle générale, seuls les processus nécessitant une interaction et doivent délibérément afficher des éléments aux utilisateurs malgré la redirection seront utilisés /dev/tty.
Stephen Harris
été là, fait ça
davidbak
10

Il y a deux problèmes.

Le premier est que l'ordre est important, le second l'est /dev/tty.

Utilisons ce script comme exemple de script à partir duquel nous voulons capturer la sortie:

test.sh:

#!/bin/bash

echo dada
echo edada 1>&2
echo ttdada >/dev/tty

Voyons maintenant les sorties des commandes:

./testmyscript.sh 2>&1 >/dev/null:

edada
ttdada

Parce que l'ordre d'évaluation est de gauche à droite, nous obtenons d'abord "rediriger stderrvers n'importe où stdoutest la sortie (donc, la sortie de la console)". Ensuite, nous obtenons "rediriger stdoutvers /dev/null. Nous nous retrouvons avec une situation comme celle-ci:

stdout-> /dev/null stderr-> console

Nous avons donc bien compris:

./testmyscript.sh >/dev/null 2>&1

Et nous obtenons:

ttdada.

Maintenant, nous faisons "Rediriger stdoutvers /dev/null", puis "Rediriger stderr vers l'endroit où stdout pointe" (donc, /dev/null). Hourra!

Cependant, nous avons toujours un problème; programme imprime sur /dev/tty. Maintenant, je ne sais pas comment résoudre ce type de comportement, vous aurez donc très probablement besoin script, mais j'espère que ce comportement ne se produira pas trop souvent.

MatthewRock
la source