Оболочка не показывает набранные команды, "сброс" работает, но что случилось?

Моя проблема в том, что оболочка Bash перестает показывать символы, которые я в нее печатаю. Это действительно читает команды все же.

Я сталкивался с этой проблемой довольно много раз, и я не понимаю, что вызывает ее. Я знаю, как решить эту проблему, но мне действительно не нравится, когда я стараюсь избавиться от проблем.

Я опишу два способа решения этой проблемы:

Я запускаю определенный процесс, http://pythonpaste.org/script/ и иногда, когда я останавливаю это или он нарушает управление, он возвращается обратно в оболочку. Когда я иду и набираю команды в оболочке, символы, которые я печатаю, не отображаются. Когда я нажимаю ввод, команды отправляются. Так, например:

  • Я набираю "ls"
  • Я вижу только пустую подсказку и больше ничего
  • Я нажимаю ввод и мне дают список файлов, другими словами: команда выполнена
  • когда я даю команду "сбросить", оболочка снова начинает нормально работать

Второй способ это происходит, когда я даю такую ​​команду:

$ grep foo * -l | xargs vim

Я использую grep для поиска файлов с определенным шаблоном, а затем хочу открыть все файлы, полученные в результате работы grep. Это работает как шарм (хотя и не так быстро, как я надеялся). Но когда я выхожу из Vim, моя оболочка перестает показывать вводимые в нее символы. Команда сброса решает проблему.

Я предполагаю, что обе проблемы имеют основную причину, но я как бы озадачен тем, как или какова эта причина.

Поиск этой проблемы сам по себе проблематичен, потому что описание является довольно расплывчатым и не содержит жестких условий поиска.

редактировать

Давая

stty --all

команда согласно запросу Джона С. Грубера дала следующий вывод (пробел, отредактированный для удобства чтения)

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 ответа

Решение

Когда запускается оболочка или большинство программ в оболочке, все, что вы вводите, возвращается в терминал пользователя подсистемой tty ядра. Есть и другая специальная обработка для стирания символов, Ctrl+R, Ctrl+Z и так далее.

Определенные программы (в частности, редакторы), которые запускаются из командной строки, не нуждаются или не хотят этого. По этой причине они сигнализируют ядру с вызовом IOCTL против tty (терминального) устройства, что они не хотят этого поведения. Они также не хотят, чтобы специальные персонажи делали особые вещи. Вместо этого они просят ядро ​​для "сырого" режима. В частности, редактор вроде vim отключает различные "настройки эха". Все это относится к реальным терминалам tty на последовательных линиях компьютера, или к виртуальным терминалам на Alt+Ctrl+F1, или к действительно виртуальным терминалам, которые вы получаете, когда вы запускаете что-то вроде gnome-терминала под GUI.

Предполагается, что такие программы сбрасывают любые режимы, которые они изменяют в виртуальном tty, который они используют, перед тем как выйти, либо путем ввода команды выхода из редактора, либо, например, путем приема сигнала (из Control+C).

Если они не могут сделать это должным образом, tty остается в забавном состоянии, которое вы обнаружили. Поскольку программы могут не выполнить сброс терминала, reset Команда была написана, чтобы позволить пользователю восстановить.

Я предполагаю, что прерывание портит программное обеспечение Python, которое вы используете. Я предполагаю, что у этой программы нет возможности перезагрузить терминал или она просто не может это сделать.

В случае vim, когда я запускаю ваш пример, я получаю то же поведение, которое вы описали. Я также вижу сообщение "Vim: Предупреждение: вход не от терминала" (он сбрасывается при сбросе). Это потому, что vim обычно не запускается из оболочки. Вместо этого команды 'grep' и 'xargs' использовали стандартный ввод, обычно занятый tty, для передачи имен файлов из grep ОТТ xargs,

В вашем опубликованном выводе от stty -a мы можем увидеть "-echo", также подтверждая, что это проблема. Если вы убьете vim таким образом, что он не сможет корректно обработать сигнал, вы, вероятно, увидите ту же проблему.

Эта проблема описана в другом месте по адресу https://stackoverflow.com/questions/3852616/xargs-with-command-that-open-editor-leaves-shell-in-weird-state.

Решение для случая vim - избегать xargs и использовать вместо этого:

 vim $(grep foo * -l)

Здесь список файлов создается оболочкой, как это было с xargs, но оболочка вызывает vim, которая напрямую связана с tty. В файл вывода ошибок отправлено предупреждающее сообщение, и vim корректно устанавливает и сбрасывает настройки tty.

Больше ссылок здесь и еще один интересный здесь. Другое интересное решение дано в ответе на https://stackoverflow.com/questions/8228831/why-does-locate-filename-xargs-vim-cause-strange-terminal-behaviour.

TL; DR; запустите это в терминале, который больше не будет отображать вводимые вами команды:

reset

Ваш терминал будет очищен и сброшен, и вы снова сможете видеть набранные команды. Обратите внимание, что при вводе resetвыше, вы ничего не увидите, поэтому может быть полезно нажать Ctrl+ C перед вводом reset чтобы очистить существующие команды или случайные символы перед запуском команды сброса.

Длинный ответ от кого-то другого: Shell не показывает набранные команды, "сброс" работает, но что случилось?

stty sane чтобы снова сделать ваш терминал "нормальным"

для повторного включения эха вводимых символов, включая специальные символы, такие как backspace

по сравнению с reset, он сохраняет историю вашего терминала / прокрутку

Я бы начал нового пользователя в системе (я имею в виду сделать нового чистого пользователя и войти в систему там), и посмотреть, есть ли проблема. Если нет - то это либо настройки терминала, либо настройки вашего X11.

Другие вопросы по тегам