Shell no muestra los comandos escritos, "reset" funciona, pero ¿qué pasó?


57

Mi problema es que el shell Bash deja de mostrar los caracteres que escribo en él. Sin embargo, sí lee los comandos.

Me he encontrado con este problema varias veces y no entiendo qué lo causa. Sé cómo resolverlo, pero realmente no me gusta cuando estoy "vudú" mi forma de salir de problemas.

Describiré las dos formas en que me he encontrado con este problema:

Estoy ejecutando un cierto proceso, http://pythonpaste.org/script/ y, a veces, cuando lo detengo o se rompe, el control se devuelve al shell. Cuando luego voy y escribo comandos en el shell, los caracteres que escribo no aparecen. Cuando presiono enter se envían los comandos . Así por ejemplo:

  • Escribo "ls"
  • Solo veo un mensaje vacío y nada más
  • Presiono enter y me dan una lista de los archivos, en otras palabras: el comando se ejecuta
  • cuando doy el comando "reset" el shell comienza a funcionar normalmente de nuevo

La segunda forma en que esto sucede es cuando doy un comando como este:

$ grep foo * -l | xargs vim

Utilizo grep para buscar archivos que tengan un cierto patrón y luego quiero abrir todos los archivos que resultan del grep. Esto funciona a las mil maravillas (aunque no tan rápido como esperaba). Pero cuando salgo de Vim, mi shell deja de mostrar los caracteres que escribo en él. Un comando de reinicio resuelve el problema.

Supongo que ambos problemas tienen una razón subyacente, pero estoy un poco perplejo sobre cómo o cuál es esa razón.

La búsqueda de este problema es problemática en sí misma porque la descripción es algo vaga y no tiene términos de búsqueda difíciles.

Editar

Dando el

stty --all

El comando según la solicitud de John S. Gruber dio el siguiente resultado (espacios en blanco editados para facilitar la lectura)

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

2
Cuando esto suceda, ingrese stty --ally ponga los resultados en su pregunta. El eco es una característica tty que se está apagando. Vim hará esto mientras se está ejecutando, y también pondrá el terminal en modo sin procesar. Cuando se cierra, debe restablecer la configuración del terminal. Cuando vim se está ejecutando, no desea repetir el icomando que pone al editor en modo de inserción, por ejemplo. Esta configuración le dice al dispositivo tty cómo debe procesar lo que escribe. Mientras vim se está ejecutando, se encarga de hacer eco de lo que debería repetirse, etc.
John S Gruber

Tengo los mismos síntomas cuando detengo Zope (con CTRL + C) cuando se ejecuta en primer plano y estoy en una sesión de depuración de ipdb.
Mark van Lent

@ MarkarkLent Creo que yo también tengo ese problema
Niels Bom

@JohnSGruber He añadido el resultado de stty --allmi pregunta. ¡Gracias por adelantado!
Niels Bom

Respuestas:


68

Cuando ejecuta un shell o la mayoría de los programas en un shell, todo lo que escribe se devuelve al terminal del usuario por el subsistema tty del kernel. También hay otro manejo especial para borrar caracteres, Ctrl + R, Ctrl + Z, etc.

Ciertos programas (en particular del editor) que se ejecutan desde una línea de comandos no necesitan ni quieren esto. Por esta razón, señalan al núcleo con una llamada IOCTL contra el dispositivo tty (terminal) que no desean este comportamiento. Tampoco quieren personajes especiales para hacer cosas especiales. En su lugar, le piden al núcleo un modo "sin procesar". En particular, los editores como vim desactivan varias "configuraciones de eco". Todo esto se aplica a terminales reales en las líneas seriales de una computadora, o las terminales virtuales en Alt + Ctrl + F1, o las terminales realmente virtuales que obtienes cuando ejecutas algo como gnome-terminal bajo una GUI.

Se supone que dichos programas restablecen cualquier modo que cambien en el tty virtual que están utilizando antes de salir, ya sea ingresando un comando de editor de cierre o tomando una señal (de Control + C), por ejemplo.

Si no lo hacen correctamente, el tty queda en el estado divertido que ha descubierto. Dado que los programas pueden fallar al restablecer el terminal, el resetcomando fue escrito para permitir que el usuario se recupere.

Supongo que la interrupción está jugando con el software de Python que está ejecutando. Supongo que ese programa no tiene la oportunidad de restablecer el terminal, o simplemente no lo hace.

En el caso vim, cuando ejecuto su ejemplo obtengo el mismo comportamiento que usted describe. También veo un mensaje "Vim: Advertencia: la entrada no proviene de un terminal" (desaparece cuando restablece). Esto se debe a que vim no se inicia normalmente desde el shell. En cambio, los comandos 'grep' y 'xargs' han estado utilizando la entrada estándar, normalmente ocupada por tty, con el fin de pasar los nombres de archivo de greptto xargs.

En su salida publicada de stty -apodemos ver "-echo", también confirmando que este es el problema. Si mataras a vim de tal manera que no pudiera manejar la señal con gracia, probablemente verías el mismo problema.

El problema se describe en otro lugar en https://stackoverflow.com/questions/3852616/xargs-with-command-that-open-editor-leaves-shell-in-weird-state .

Una solución para el caso vim es evitar xargs y usar en su lugar:

 vim $(grep foo * -l)

Aquí la lista de archivos está construida por el shell, como lo había sido por xargs, pero el shell está llamando a vim, que está directamente conectado al tty. Hay un mensaje de advertencia enviado al archivo de salida de error, y vim establece y restablece la configuración de tty correctamente.

Más referencias aquí , y otra interesante aquí . Otra solución interesante se da en una respuesta a https://stackoverflow.com/questions/8228831/why-does-locate-filename-xargs-vim-cause-strange-terminal-behaviour .


Gracias por la explicación detallada. La razón completa por la que esto no funciona parece un rabbithole bastante profundo (tty, ioctl, etc.), así que no puedo decir que entiendo completamente, pero ya no es vudú, ¡así que gracias de nuevo!
Niels Bom

Para estar completo puedo ejecutar grep foo * -l | vim -sin problemas. Así que creo que el problema no es con grep y xargs, sino solo con xargs. ¿Estarías de acuerdo?
Niels Bom

1
No es un problema con grep o xargs. Es un problema con el hecho de que stdin ya no está configurado en tty. Esto también falla `cierto | vi / tmp / afile1. Una de las referencias menciona que vim establece stdin en stdout (aún el tty) porque stdin se ha establecido en / dev / null en estas situaciones. Cuando lo hace, vim puede recordar y restablecer el eco y otras configuraciones, pero no lo hace. Creo que este es un problema con vim.
John S Gruber

Esto fue muy útil ya que me he encontrado con esto. Se sintió al azar, pero apuesto a que siempre fue cuando intentaba hacer algo con vi que no salía limpiamente o usaba una tubería.
Michael Mathews

1
¡Gracias! Finalmente descubrí cómo recuperarse en OS X bash después de un ctrl-c para git add -p!
Steve Jansen el

0

Comenzaría un nuevo usuario en el sistema (quiero decir, crear un nuevo usuario limpio e iniciar sesión allí), y ver si el problema está ahí. Si no es así, entonces es su terminal o su configuración X11.


Agregué un nuevo usuario y probé esto con el grep foo * -l | xargs vimcomando. El problema aún existe. No entiendo exactamente cómo mi configuración de X11 podría influir en cómo reacciona mi terminal por cierto. ¿Podrías dar más detalles sobre eso? ¡Gracias!
Niels Bom
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.