Bash i zawijanie linii

Bash ma historię wpisywanych w terminal rzeczy. To bardzo dobrze. Używając strzałek w górę oraz w dół można przeglądać ostatnio wpisywane rzeczy. To również bardzo dobrze. W czym więc problem? Skąd właściwie bash wie, gdzie kończy się nasz prompt, a zaczyna historia? Skąd wie, gdzie umieścić znaki polecenia, które przekracza jedną linię?

Ano może sobie policzyć na której kolumnie terminala kończy się prompt, a na której zaczyna moje pisanie. Problem jest taki, że Bash liczy sobie znaki niedrukowane, na przykład kody kolorów, czy inne tego typu rzeczy. Oczywiście rachunek wychodzi błędnie, ponieważ ilość znaków w PS1 nie równa się tym wypisywanym na terminalu. Wynikiem tego są takie kwiatki:

[ lukasz@GAZEvim .bashrc

Jak temu zaradzić? Obszerne wyjaśnienie problemu jest na stronie Stack Exchange. Ja podam tylko wybrane przeze mnie rozwiązanie, polegające na wyciągnięciu niedrukowanych znaków do zmiennych i opatrzeniu ich numerkami:

green="\001$(tput setaf 2)\002"
blue="\001$(tput setaf 4)\002"
dim="\001$(tput dim)\002"
reset="\001$(tput sgr0)\002"
PS1="$green\u@\h $blue $ \n  $green->$reset  "
export PS1
unset green blue dim reset

Ło matko, co to jest? W zmiennych z kolorami oraz zmiennej resetującej kolor tłumaczymy Bashowi jak krowie na polu, że $(tput setaf 2) ma liczyć jako jeden znak. Czy te zmienne są niezbędne? Nie, ale bez nich czytelność linijki PS1 byłaby niewielka. Nazwy tych zmiennych oraz kolory ustawiane setafem nie mają oczywiście znaczenia. Dzięki nim unikamy znaków niedrukowanych w prompcie i bash wie, gdzie zacząć moje pisanie.

Ten wpis został opublikowany w kategorii #!/kody i oznaczony tagami , . Dodaj zakładkę do bezpośredniego odnośnika.