web-dev-qa-db-fra.com

Shell n'affiche pas les commandes saisies, "reset" fonctionne, mais que s'est-il passé?

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

J'ai rencontré ce problème plusieurs fois et je ne comprends pas ce qui le cause. Je sais comment le résoudre, mais je n'aime vraiment pas quand je "voodoo" ma façon de résoudre les problèmes.

Je vais décrire les deux manières par lesquelles j'ai rencontré ce problème:

J'exécute un certain processus, http://pythonpaste.org/script/ et parfois, quand j'arrête ça ou que ça casse, le contrôle est rendu au shell. Lorsque je saisis ensuite des commandes dans le shell, les caractères que je saisis n'apparaissent pas. Lorsque j'appuie sur entrer, 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 on me donne 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 manière que cela se produit est quand je donne une commande comme ceci:

$ grep foo * -l | xargs vim

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

J'imagine que les deux problèmes ont une raison sous-jacente, mais je ne comprends pas très bien comment ou quelle est cette raison.

La recherche de ce problème est en soi problématique car la description est assez vague et ne contient pas de termes de recherche durs.

Modifier

Donner le

stty --all

commande selon la demande de John S. Gruber a donné le résultat suivant (espace modifié pour la 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
55
Niels Bom

Lorsque vous exécutez un shell ou la plupart des programmes dans un shell, tout ce que vous tapez est renvoyé au terminal de l'utilisateur par le sous-système tty du noyau. Il existe également d'autres méthodes spéciales pour effacer des caractères, Ctrl + R, Ctrl + Z, etc.

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

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

S'ils ne le font pas correctement, le terminal est laissé dans l'état amusant que vous avez découvert. Étant donné que les programmes peuvent ne pas réussir à réinitialiser le terminal, la commande reset a été écrite pour permettre à l'utilisateur de récupérer.

Je suppose que l'interruption concerne le logiciel python que vous utilisez. J'imagine 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 j'exécute votre exemple, le comportement que vous décrivez est identique. Je vois aussi le message "Vim: Avertissement: l’entrée ne provient pas d’un terminal" (elle disparaît lorsque vous réinitialisez). En effet, vim n’est pas démarré normalement à partir du shell. Au lieu de cela, les commandes 'grep' et 'xargs' ont utilisé l'entrée standard, normalement occupée par le terminal, pour transmettre les noms de fichier de grepttoxargs.

Dans votre résultat posté de stty -a, nous pouvons voir "-echo", confirmant également que c'est le problème. Si vous deviez tuer vim de telle sorte qu'il ne puisse pas gérer le signal avec élégance, vous verriez probablement le même problème.

Le problème est décrit ailleurs dans https://stackoverflow.com/questions/3852616/xargs-with-command-that-open-editor-leaves-Shell-in-weird-state .

Une solution pour le cas vim est d’éviter xargs et d’utiliser plutôt:

 vim $(grep foo * -l)

Ici, la liste des fichiers est construite par le shell, comme 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 donnée dans une réponse à https://stackoverflow.com/questions/8228831/why-does-locate-filename-xargs-vim-cause-strange-terminal-behaviour .

65
John S Gruber

Je commencerais un nouvel utilisateur sur le système (je veux dire créer un nouvel utilisateur et me connecter ici), et voir si le problème est là. Si ce n'est pas le cas, il s'agit alors des paramètres de Votre terminal ou de Votre X11.

0
Adobe