Shell ne s'affiche pas dans les commandes tapées, "reset" fonctionne, mais que s'est-il passé?

43

Mon problème est que le shell Bash cesse de montrer les caractères que je saisis. Il lit les commandes cependant.

J'ai rencontré ce problème à plusieurs reprises et je ne comprends pas ce qui le cause. Je sais comment le résoudre, mais je ne l'aime pas vraiment quand je "voodooing" ma façon de sortir des problèmes.

Je vais décrire les deux façons dont j'ai rencontré ce problème:

J'exécute un certain processus, lien et parfois, lorsque j'arrête ou que le contrôle est interrompu, il est renvoyé au shell. Lorsque je vais ensuite taper des commandes dans le shell, les caractères que je tape ne s'affichent pas. Lorsque j'appuie sur Entrée, les commandes sont soumises. Donc par exemple:

  • Je tape "ls"
  • Je ne vois qu'une invite vide et rien de plus
  • J'appuie sur Entrée et je reçois une liste des fichiers, en d’autres termes: la commande est exécutée
  • quand je donne la commande "reset", le shell recommence à fonctionner normalement

La deuxième façon de procéder est lorsque je donne une commande comme celle-ci:

$ grep foo * -l | xargs vim

J'utilise grep pour trouver les fichiers qui ont un certain modèle, puis je veux ouvrir tous les fichiers résultant de grep. Cela fonctionne comme un charme (mais pas aussi vite que je l'espérais). Mais quand je quitte Vim, mon shell ne montre plus les caractères que je saisis. Une commande de réinitialisation résout le problème.

Je pense que les deux problèmes ont une raison sous-jacente, mais je suis un peu déconcerté par la façon ou la nature de cette raison.

La recherche de ce problème est elle-même problématique car la description est plutôt vague et n’a pas de termes de recherche rigoureux.

Modifier

Donner le

stty --all
La commande

selon la requête de John S. Gruber a donné la sortie suivante (espace blanc modifié pour une meilleure lisibilité)

speed 0 baud;
rows 53;
columns 186;
line = 0;
intr = <undef>;
quit = <undef>;
erase = <undef>;
kill = <undef>; 
eof = <undef>;
eol = <undef>; 
eol2 = <undef>; 
swtch = <undef>; 
start = <undef>; 
stop = <undef>; 
susp = <undef>;
rprnt = <undef>; 
werase = <undef>; 
lnext = <undef>; 
flush = <undef>; 
min = 0; 
time = 0;
-parenb 
-parodd cs8 
-hupcl 
-cstopb cread 
-clocal 
-crtscts
-ignbrk 
-brkint 
-ignpar 
-parmrk 
-inpck 
-istrip 
-inlcr 
-igncr 
-icrnl 
-ixon 
-ixoff 
-iuclc 
-ixany 
-imaxbel 
-iutf8
-opost 
-olcuc 
-ocrnl 
-onlcr 
-onocr 
-onlret 
-ofill 
-ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig 
-icanon 
-iexten 
-echo 
-echoe 
-echok 
-echonl 
-noflsh 
-xcase 
-tostop 
-echoprt 
-echoctl 
-echoke
    
posée Niels Bom 03.08.2012 - 10:15
la source

2 réponses

49

Lors de l'exécution d'un shell ou de la plupart des programmes d'un shell, tout ce que vous tapez est renvoyé au terminal de l'utilisateur par le sous-système tty du noyau. Il y a aussi d'autres manipulations spéciales pour effacer des caractères, Ctrl + R, Ctrl + Z, etc.

Certains programmes (notamment ceux de l’éditeur) exécutés à partir d’une ligne de commande n’en ont pas besoin. Pour cette raison, ils signalent au noyau un appel IOCTL contre le périphérique tty (terminal) pour qu'ils ne souhaitent pas ce comportement. Ils ne veulent pas non plus que des caractères spéciaux fassent des choses spéciales. Au lieu de cela, ils demandent au noyau un mode "brut". En particulier, les éditeurs comme vim désactivent divers "paramètres d'écho". Tout cela s'applique aux terminaux tty réels sur les lignes série d'un ordinateur, ou aux terminaux virtuels à Alt + Ctrl + F1, ou aux terminaux réellement virtuels que vous obtenez lorsque vous utilisez quelque chose comme gnome-terminal sous une interface graphique.

Ces programmes sont supposés réinitialiser tous les modes qu’ils modifient sur le tty virtuel qu’ils utilisent avant de quitter, soit en entrant une commande de fermeture de l’éditeur, soit en prenant un signal (depuis Control + C) par exemple.

S'ils ne le font pas correctement, le tty reste dans l’état drôle que vous avez découvert. Comme les programmes ne parviennent pas à réinitialiser le terminal, la commande reset a été écrite pour permettre à l'utilisateur de récupérer.

Je suppose que l’interruption perturbe le logiciel python que vous utilisez. Je suppose que ce programme n’a pas la possibilité de réinitialiser le terminal ou ne le fait tout simplement pas.

Dans le cas vim, lorsque je lance votre exemple, je reçois le même comportement que vous décrivez. Je vois aussi un message "Vim: Attention: l’entrée ne provient pas d’un terminal" (elle disparaît lors de la réinitialisation). C'est parce que vim n'est pas démarré normalement à partir du shell. Au lieu de cela, les commandes 'grep' et 'xargs' utilisaient l'entrée standard, normalement occupée par le tty, pour transmettre les noms de fichiers de grep tto xargs .

Dans votre sortie de stty -a , nous pouvons voir "-echo", confirmant également que c'est le problème. Si vous deviez tuer vim de manière à ce qu'il ne puisse pas gérer le signal, vous rencontreriez probablement le même problème.

Le problème est décrit ailleurs à lien .

Une solution pour le cas vim est d'éviter xargs et d'utiliser à la place:

 vim $(grep foo * -l)

Ici, la liste des fichiers est construite par le shell, comme cela a été le cas par xargs, mais le shell appelle vim, qui est directement connecté au tty. Un message d'avertissement est envoyé au fichier de sortie d'erreur, et vim définit et réinitialise correctement les paramètres tty.

Plus de références ici et une autre intéressante ici . Une autre solution intéressante est la réponse à lien .

    
réponse donnée John S Gruber 06.08.2012 - 23:16
la source
0

Je commence un nouvel utilisateur sur le système (je veux dire créer un nouvel utilisateur propre et vous y connecter), et voir si le problème est là. Si ce n'est pas le cas, il s'agit de votre terminal ou de vos paramètres X11.

    
réponse donnée Adobe 03.08.2012 - 16:43
la source

Lire d'autres questions sur les étiquettes