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

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, il m'arrive parfois d'get 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 lorsque je fais &2>1 > file , je vois toujours l'avis.

Et il en va de même pour emerge : Quand j'exécute emerge et qu'il y a des problèmes, certaines informations ne sont pas imprimées sur stdout ni stdin , puisque je les redirige et qu'elles passent toujours.

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

La syntaxe que vous avez utilisée est incorrecte.

 cmd &2>1 >file 

sera divisé en tant que

 cmd & 2>1 >file 

Cette volonté

  1. Exécuter cmd comme travail d'arrière-plan sans redirections
  2. Dans un process séparé (sans command!) Redirige stderr vers un file appelé littéralement 1 et redirige stdout vers le file

La syntaxe que vous voulez est

 cmd >file 2>&1 

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

  1. Rediriger stdout vers le file
  2. Rediriger stderr vers &1 – c'est-à-dire le même descripteur de file que stdout

Le résultat est que stderr et stdout seront redirigés vers le file .

En bash un non-standard plus simple (et donc je ne le recommand pas, sur des raisons de portabilité) de la syntaxe du cmd &> file fait la même chose.

Il y a deux problèmes.

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

Utilisons ce script comme exemple de script que nous voulons capturer en sortie:

test.sh :

 #!/bin/bash echo dada echo edada 1>&2 echo ttdada >/dev/tty 

Voyons maintenant les sorties des commands:

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

 edada ttdada 

Parce que l'ordre d'évaluation est de gauche à droite, nous obtenons d'abord "redirect stderr à l'endroit où stdout est sortant (donc, la sortie de la console)". Ensuite, nous obtenons "redirect stdout to /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 stdout vers /dev/null ", puis "Rediriger stderr vers où stdout pointe" (donc, /dev/null ). Hourra!

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