Linux moins de comportement et stderr


11

J'observe la sortie de ma commande compliquée avec less, le problème est la stderrse perd. stderrles lignes sont normalement listées entre les stdoutlignes à l'intérieur less. Je voudrais qu'ils soient imprimés sur la console, et à ma sortie less, pour les voir ensemble.

Je me rends compte qu'il n'y a peut-être pas de solution à cela, j'ai lu teeet multiteemais aucune chance jusqu'à présent.


2
Vous me dites comment rediriger stderr vers stdout mais ce n'est pas ce que je voulais. Je ne veux pas que stderr se mélange avec stdout inside less. J'aimerais que stderr soit dans le terminal quand je quitte moins.

Si stderrest redirigé vers stdout, toutes les sorties vers stderr seront mélangées avec la sortie normale activée stdout. La canalisation de cette sortie lessaffichera les deux.
Un programmeur du

Si j'ignore "stderr pour être dans le terminal quand je quitte moins", je suggère d'appuyer sur Ctrl-L lesspour repeindre l'écran.
kamae

Réponses:


10

Peut être

command 2> command.err | less; cat command.err; rm command.err

Addenda

Voici une clarification pour les gens qui négligent de lire attentivement la question et qui n'ont pas lu le commentaire de clarification du PO ci-dessus.

haelix a souligné:

les lignes stderr sont normalement répertoriées entre les lignes stdout à l'intérieur de moins

et, dans un commentaire pour les premiers intervenants, a écrit:

Vous me dites comment rediriger stderr vers stdout mais ce n'est pas ce que je voulais. Je ne veux pas que stderr se mélange avec stdout inside less. J'aimerais que stderr soit dans le terminal quand je quitte moins

Le problème est probablement spécifique à la plate-forme, c'est certainement quelque chose que j'ai vécu sur les anciennes plates-formes Unix SVR4.

Si, sur de telles plateformes, vous faites quelque chose comme

 find / ... | less

tous les messages d'erreur (par exemple les autorisations de répertoire) apparaissent comme ceci en moins

 stdout line 1
 stdout line 2
 error message text
 stdout line 4

afin que les lignes de sortie soient masquées par des messages d'erreur.

Si vous actualisez la page, les lignes de sortie s'affichent correctement mais vous perdez les messages d'erreur. Lorsque vous quittez moins, l'écran est effacé, à l'exception d'une invite de commande.

Si vous faites quelque chose comme

  find / ... 2>&1 | less

Les messages d'erreur sont entremêlés avec la sortie standard. Encore une fois lorsque vous quittez moins, l'écran est vide.

Si vous voulez d'abord parcourir uniquement la sortie standard en moins, puis voir les messages d'erreur après avoir quitté less, vous avez besoin d'une solution différente.

C'est ce que je proposais provisoirement dans ma réponse originale en deux lignes.


Ce sont des ordures. La réponse de Joachim devrait être celle acceptée.
Vanilla Face

2
@VanillaFace: J'ai ajouté des éléments de clarification à ma réponse.
RedGrittyBrick

15

Vous devez rediriger stderrvers stdout:

$ ./somecommad 2>&1 | less

Consultez le manuel de votre shell (par exemple man bash.)


1
Commentaire pour les nouveaux lecteurs de cette vieille question (pas pour Joachim en particulier) C'est ce que tout le monde pense au premier scan de la question. Mais le problème est plus subtil - voir la discussion dans les commentaires après la réponse de
dmckee

1

il suffit de dire au shell de rediriger fd 2 vers fd 1 (stderr vers stdout)

 make 2>&1 | less

1

Une chose qui manquait jusqu'à présent dans toutes les réponses est la raison pour laquelle cela se produit. Le problème ici est une sorte de condition de concurrence entre la sortie du processus stderret l' lessaffichage de la sortie stdoutsur le terminal. Si lesscommence à s'afficher une fois que toutes les sorties de stderront été imprimées sur le terminal, lesscela les conservera et vous pourrez voir les messages après la sortie less. OTOH si lessa déjà commencé à afficher des éléments, les messages d'erreur s'entremêlent avec lessla sortie de et rien n'est conservé après les lesssorties (car lesspréserve simplement le terminal tel qu'il était avant son démarrage et ne sait rien des messages d'erreur qui se sont produits entre les deux).

Vous pouvez le voir facilement, par exemple

grep foo -r /etc | less

Tous les messages d'erreur "Autorisation refusée" se mélangent avec la lesssortie et rien ne sera là après votre sortie. Si tu fais

grep foo -r /etc | (sleep 10; less)

tous (ou au moins la plupart) des messages d'erreur ont été imprimés sur le terminal avant d' lessavoir la possibilité d'afficher la sortie et vous verrez les messages d'erreur par la suite.

Bien sûr, vous ne voulez généralement pas attendre 10 secondes avant de commencer less, mais avec Linux, vous pouvez également fournir des valeurs fractionnaires pour le temps d'attente, et avec des processus rapides, souvent quelque chose d'aussi peu que sleep 0.1suffisant pour éviter la condition de concurrence. (Mais, bien sûr, si vous voulez ou devez être du côté vraiment sûr, utilisez la solution de RedGrittyBrick).


0

Vous devez comprendre le concept de "descripteurs de fichiers". Habituellement, une application Unix démarre avec trois descripteurs de fichiers spéciaux:

  • Entrée standard
  • Sortie standard
  • Erreur standard

Le "tuyau" |dans la coque se connecte stdoutd'un processus stdinau suivant.

De par leur conception, les erreurs ne sont pas transmises au stdinprocessus suivant. Souvent, ils n'auront pas de sens pour l'application suivante et ne devraient pas être cachés à l'utilisateur.

Si vous voulez mélanger les erreurs dans stdout, vous pouvez utiliser par exemple 2>&1, qui dit essentiellement "ajouter stderr à stdout". Par exemple

find /etc 2>&1 | less

devrait également inclure la sortie d'erreur de fichiers inaccessibles.

find /etc 2>&1 >/dev/null | less

vous donnera uniquement les erreurs.


0

Je suis confus au sujet de votre question, pour autant que je puisse dire que votre comportement souhaité est celui par défaut.

Quand j'utilise

#include <stdio.h>

int main(int argc, char**argv){
  for (int j=0; j<10; ++j){
    fprintf( (j%2 ? stdout : stderr) , "%d\n" , j);
  }
  return 0;
}

pour obtenir un test simple,

$ ./testredirection | less

fait exactement ce que vous demandez. C'est que je vois

1
3
5
7
9
(END) 

dans lesset

$ ./testredirection | less
0
2
4
6
8
$ 

quand je quitte less


C'est étrange mais les choses ne sont pas toujours comme ça. Essayez avec un script ( echo info ; echo error 1>&2) et répétez le test: les deux lignes sont dirigées vers moins.
cYrus

@cYrus: Cela fonctionne comme prévu pour moi aussi. «Bien sûr, j'ai essayé sur une boîte Mac OS. Bash 3.2.17, moins 394. Peut-être quelque chose de spécifique à Linux. Dans tous les cas, l'approche de RedGrittyBrick devrait fonctionner correctement.
dmckee --- chaton ex-modérateur

Bizarre! Debian Squeeze / Bash 4.1.5 / Less 436
cYrus

Oui, j'ai ouvert un shell de la boîte de Scientific Linux 5.3 au travail et j'ai obtenu le comportement attendu avec bash 3.0.15 et moins 382. Pourrait-il y avoir une régression?
dmckee --- chaton ex-modérateur

Je ne sais pas, je pense que c'est juste une question de mise en mémoire tampon.
cYrus

0

Il se trouve que je rencontre ce problème dans l'un de mes Debian 5.0 récemment. par exemple, ls abc | moins je trouve que le message d'erreur va dans moins, ce qui contre ma connaissance.

Après quelques tentatives, j'ai trouvé que c'était juste quelque chose lié aux tampons d'écran. stderr n'entre PAS dans moins en fait. Vous pouvez utiliser les touches fléchées Haut ou Bas (ou j / k) pour démontrer.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.