Mój problem polega na tym, że powłoka Bash przestaje pokazywać znaki, które do niej wpisuję. Czyta jednak polecenia.
Z tym problemem spotkałem się już kilka razy i nie rozumiem, co go powoduje. Wiem, jak to rozwiązać, ale nie podoba mi się to, kiedy „wuduję” swoją drogę wyjścia z problemów.
Opiszę dwa sposoby, w jakie napotkałem ten problem:
Pracuję nad pewnym procesem, http://pythonpaste.org/script/, a czasami, kiedy go zatrzymuję lub psuje kontrolę, wraca do powłoki. Kiedy idę i wpisuję polecenia w powłoce, znaki, które wpisuję, nie pojawiają się. Po naciśnięciu Enter polecenia są przesyłane. Na przykład:
- Piszę „ls”
- Widzę tylko pusty monit i nic więcej
- Naciskam Enter i wyświetla się lista plików, innymi słowy: polecenie jest wykonywane
- po wydaniu polecenia „reset” powłoka znów zaczyna normalnie działać
Drugi sposób to się dzieje, gdy wydajemy takie polecenie:
$ grep foo * -l | xargs vim
Używam grep, aby znaleźć pliki, które mają określony wzorzec, a następnie chcę otworzyć wszystkie pliki wynikające z grep. Działa to jak urok (choć nie tak szybko, jak się spodziewałem). Ale kiedy wychodzę z Vima, moja powłoka przestaje pokazywać znaki, które do niej wpisuję. Polecenie resetu rozwiązuje problem.
Domyślam się, że oba problemy mają przyczynę leżącą u podstaw, ale jestem trochę zakłopotany tym, jak i czym jest ten powód.
Samo poszukiwanie tego problemu jest problematyczne, ponieważ opis jest niejasny i nie ma dla niego trudnych warunków wyszukiwania.
Edytować
Dając
stty --all
polecenie zgodnie z żądaniem Johna S. Grubera dało następujące dane wyjściowe (białe znaki edytowane dla czytelności)
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
źródło
stty --all
i wpisz wyniki w swoim pytaniu. Echo jest wyłączaną cechą tty. Vim zrobi to, gdy jest uruchomiony, i przełączy terminal również w tryb surowy. Po wyjściu powinien zresetować ustawienia terminala. Kiedy vim działa, nie chcesz powtarzaći
polecenia, które przełącza edytor w tryb wstawiania, na przykład. Te ustawienia mówią urządzeniu tty, jak powinno przetwarzać to, co wpisujesz. Podczas działania vima dba o echo tego, co powinno zostać powtórzone itp.stty --all
do mojego pytania. Z góry dziękuję!Odpowiedzi:
Podczas uruchamiania powłoki lub większości programów w powłoce wszystko, co wpiszesz, jest wysyłane z powrotem do terminala użytkownika przez podsystem tty jądra. Istnieje również inna specjalna obsługa usuwania znaków, Ctrl + R, Ctrl + Z i tak dalej.
Niektóre programy (w szczególności edytora), które działają z wiersza poleceń, nie potrzebują tego ani nie chcą. Z tego powodu sygnalizują jądro wywołaniem IOCTL przeciwko urządzeniu tty (terminalowi), że nie chcą tego zachowania. Nie chcą też, aby znaki specjalne robiły specjalne rzeczy. Zamiast tego pytają jądro o tryb „raw”. W szczególności edytory takie jak vim wyłączają różne „ustawienia echa”. Wszystko to dotyczy prawdziwych terminali tty na liniach szeregowych komputera, wirtualnych terminali w Alt + Ctrl + F1 lub naprawdę wirtualnych terminali, które otrzymujesz, gdy uruchamiasz coś takiego jak gnome-terminal pod GUI.
Takie programy powinny resetować wszystkie tryby, które zmieniają na wirtualnym terminalu, z którego korzystają przed wyjściem, na przykład poprzez wprowadzenie polecenia wyjścia z edytora lub na przykład odebrania sygnału (z Control + C).
Jeśli nie zrobią tego poprawnie, tty pozostaje w zabawnym stanie, który odkryłeś. Ponieważ programy nie mogą zresetować terminala,
reset
polecenie zostało napisane, aby umożliwić użytkownikowi odzyskanie.Zakładam, że przerwanie nie działa z uruchomionym oprogramowaniem Pythona. Sądzę, że ten program nie ma szansy na zresetowanie terminala lub po prostu tego nie robi.
W przypadku vim, kiedy uruchomię twój przykład, otrzymuję to samo zachowanie, które opisujesz. Widzę także komunikat „Vim: Ostrzeżenie: Dane wejściowe nie pochodzą z terminala” (znika po zresetowaniu). Wynika to z faktu, że vim nie jest uruchamiany normalnie z powłoki. Zamiast tego polecenia „grep” i „xargs” używają standardowego wejścia, zwykle zajmowanego przez tty, do przekazywania nazw plików z
grep
ttoxargs
.W opublikowanym wyjściu z
stty -a
możemy zobaczyć „-echo”, również potwierdzające, że to jest problem. Jeśli miałbyś zabić Vima w taki sposób, że nie byłby w stanie z wdziękiem poradzić sobie z sygnałem, prawdopodobnie zobaczyłbyś ten sam problem.Problem opisano w innym miejscu na https://stackoverflow.com/questions/3852616/xargs-with-command-that-open-editor-leaves-shell-in-weird-state .
Rozwiązaniem w przypadku vima jest uniknięcie xargs i użycie zamiast tego:
Tutaj lista plików jest budowana przez powłokę, podobnie jak xargs, ale powłoka wywołuje vim, który jest bezpośrednio podłączony do tty. Do pliku wyjściowego błędu wysyłany jest komunikat ostrzegawczy, a vim poprawnie ustawia i resetuje ustawienia tty.
Więcej referencji tutaj i kolejna interesująca tutaj . Inne interesujące rozwiązanie podano w odpowiedzi na https://stackoverflow.com/questions/8228831/hy-does-locate-filename-xargs-vim-cause-strange-terminal-behaviour .
źródło
grep foo * -l | vim -
bez problemów. Myślę więc, że problem nie dotyczy grep i xargs, ale tylko xargs. Zgodziłbyś się?git add -p
!Założyłbym nowego użytkownika w systemie (mam na myśli utworzenie nowego, czystego użytkownika i zalogowanie się tam) i sprawdzenie, czy problem nie istnieje. Jeśli nie, to albo Twój terminal, albo ustawienia X11.
źródło
grep foo * -l | xargs vim
polecenia. Problem nadal istnieje. Nie do końca rozumiem, jak moje ustawienia X11 mogą wpłynąć na to, jak mój terminal reaguje btw. Czy mógłbyś to rozwinąć? Dzięki!