Dlaczego ten monit bash czasami zachowuje część poprzednich poleceń podczas przewijania historii?

29

Mój monit bash, który muszę przyznać, że ukradłem z kilku miejsc i zebrał razem, czasami dodaje część poprzednich poleceń do jego długości podczas przewijania historii bashu za pomocą strzałek w górę / w dół.

Na przykład, jeśli moje poprzednie polecenia to:

ls
cd /home/caleb
vim .bashrc

Gdy zobaczyłem monit i dwa razy przewinąłem w górę, może to wyglądać następująco:

$ vim .bcd / home / caleb

Gdzie pozostało pierwszych pięć znaków z ostatniego polecenia.

Czy ktoś ma pojęcie, dlaczego tak się dzieje i jak można to zatrzymać?

Mój monit jest ustawiony przy użyciu tego kodu (sposób, aby dodać tutaj): https://gist.github.com/1679352

Caleb Thompson
źródło
1
Ustaw PS1 na wartość bez całego badziewia vcs i zobacz, co się stanie. Tak sądzę.
Daniel Beck
Czy znalazłeś już winowajcę w swoim znaku zachęty? Mam ten sam problem.
acme
Tak, bash traci to na kolorach i nie jest w stanie oddzielić długości łańcuchów, a kolor ucieka od długości widocznego łańcucha. Do tego zmierzał SiegeX. Skończyło się na przejściu na ZSH i użyciu innego monitu. ZSH nie ma tego samego problemu.
Caleb Thompson,
1
Obie poprzednie odpowiedzi nie rozwiązały mojego problemu i nie wyjaśniły, dlaczego tak się stało. Sprawdź, czy monit Custom Bash się nadpisuje , jeśli ktoś szukał tego punktu.
D3Hunter,
Powiązany problem unix.stackexchange.com/questions/105958/…
matthiasbe

Odpowiedzi:

6

Gdzieś twój monit jest fubar. Zwykle zdarza się, że powłoka myśli, że generuje kody terminów niedrukowalnych i oczekuje, że zajmie miejsce. Najlepszą radą, jaką mogę ci dać, jest systematyczne dodawanie (lub odejmowanie) pytania, dopóki to zachowanie nie ustanie, aby wyodrębnić kod powodujący ten problem.

SiegeX
źródło
37

Kody kolorów należy owinąć w nawiasy kwadratowe. Nawiasy informują bash, że załączony tekst nie powinien być drukowany

bazując na przykładzie @ Phreditor, pokazuje to, że każde formatowanie wykonane po nowej linii spowoduje powstanie oryginalnego problemu:

export PS1="\n\n\[\033[01;33m[\w]\033[00m\n\033[0;90m\$ "

zawinięcie kodu formatu w [] gwarantuje, że nigdy nie nastąpi irytujące zachowanie:

export PS1="\n\[\[\033[01;33m\][\w]\[\033[00m\]\n\[\033[0;90m\]\$ "

Dokumentacja: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/nonprintingchars.html

Ponieważ formatowanie PS1 powoduje, że wartość jest tak długa i trudna do odczytania, umieszczam kody formatu w zmiennych:

BYELLOW='\[\033[01;33m\]'
IBLACK='\[\033[0;90m\]'
PS_CLEAR='\[\033[0m\]'
export PS1="\n${BYELLOW}[\w]${PS_CLEAR}\n${IBLACK}\$ "
m79lkm
źródło
3
To powinna być zaakceptowana odpowiedź. Rozwiązał problem.
Atcold,
1
Należy zauważyć (ponieważ tego nie zauważyłem;)), że w tym bałaganie ukośników odwrotnych i nawiasów kwadratowych nawiasy kwadratowe następujące po sekwencji ucieczki \033NIE powinny być uciekane. Należy uciec tylko owiniętym nawiasom kwadratowym.
Benjam
Sposób na mylące dla mnie radzenie sobie ze wszystkimi tymi znakami specjalnymi, użycie pierwszego wyniku Google pomogło wygenerować działający monit dokładnie tak, jak tego chciałem: ezprompt.net
Mallox
Chciałem dostosować moje szybkie kolory na LATA, ale nigdy tego nie miałem, ponieważ zawsze miałem ten problem! Nigdy nie mogłem zrozumieć, dlaczego tak się zatrzymałem i utrzymałem wszystko na biało ... Właśnie konfigurowałem nowy komputer i wreszcie przyszło mi do głowy, że problem z Google'em ... Tak się cieszę, że tak zrobiłem! Dziękuję za tę cudowną lekcję.
TylerH4
8

Miałem ten sam problem i był on związany z definicjami kolorów.

W moim przypadku mam wieloliniowy monit (daje najwięcej miejsca na bieżące polecenie, niezależnie od długości ścieżki wyświetlanej przez monit).

Zła wersja:

export PS1="\n\n\[\033[01;33m[\w]\n\033[00m\$ "

Dobra wersja:

export PS1="\n\n\[\033[01;33m[\w]\033[00m\n\$ "

\033[00mkończy kolor. Jeśli jest za nową linią ( \n), uniemożliwia prawidłowe przerysowanie w terminalu, aby zastąpić poprzednie polecenia kolorem tła. Przesunięcie go za nową linię rozwiązało problem.

(za pomocą terminala w systemie Mac OS 10.8)

Freditor
źródło
Wskazało mi to na problem, podczas gdy obecna zaakceptowana odpowiedź była zbyt ogólna.
Brian,
To jest bardziej precyzyjna odpowiedź i powinna być zwycięzcą (i było również rozwiązaniem mojego problemu).
craveytrain
\nbyły winowajcą dla mnie też. Dzięki!
mhulse
3

Myślę, że ma to związek z brakującym ogranicznikiem „znaków niedrukowalnych”. Miałem dokładnie ten sam problem, ale przeniesienie go przed nową linią (\ n) nie rozwiązało problemu. Zamiast tego poprawnie otoczyłem wszystkie niedrukowalne znaki (tutaj polecenia kolorowania) znakami „\ [” i „\]”.

Źle (działa, ale ma opisany powyżej problem łączenia historii):

PS1="\e[32m\u\e[35m@\e[32m\h \e[33m\w\e[36m\n\$\e[0m"

Dobra (otoczona wszystkimi komendami kolorów za pomocą „\ [” i „\]” - nie pokazuje historii poleceń):

PS1="\[\e[32m\]\u\[\e[35m\]@\[\e[32m\]\h \[\e[33m\]\w\[\e[36m\]\n\$\[\e[0m\]"

i.e. "\e[...m" --becomes--> "\[\e[...m\]"

A jeśli wstawiasz to do czegoś takiego jak SecureCRT, aby automatycznie wysyłać po zalogowaniu do systemu, być może będziesz musiał podwójnie uciec od wszystkiego (umieść wszędzie podwójne ukośniki odwrotne), jeśli system automatycznego logowania używa pierwszego ukośnika odwrotnego, aby określić znak, który ma zostać wysłany :

PS1="\\[\\e[32m\\]\\u\\[\\e[35m\\]@\\[\\e[32m\\]\\h \\[\\e[33m\\]\\w\\[\\e[36m\\]\\n\\$\\[\\e[0m\\]"

i.e. "\..." --becomes--> "\\..."

(Jest to z pewnością prawdziwe w przypadku SecureCRT i może być prawdziwe w przypadku innych, takich jak PuTTY lub TeraTerm - testowanie wymagane z Twojej strony.)

skeetastax
źródło