Artur Pyszczuk's blog...

"The code that is the hardest to debug is the code that you know cannot possibly be wrong."
Unknown
/home/linux/prompt/

Zmiana znaku zachęty (prompt)

Jeśli myślałeś kiedyś o zmianie znaku zachęty z domyślnego na dowolny jaki byś tylko chciał, to w tym miejscu przedstawię dość dokładnie w jaki sposób to zrobić. O co tak właściwie chodzi? A więc już tłumaczę. Pod tym linkiem znajduje się domyślny wygląd znaku zachęty w Ubuntu. Jeśli chcesz, aby Twój terminal wyglądał na przykład tak jak pokazano na poniższym rysunku - czytaj dalej tę stronę, a napewno dowiesz się jak to zrobić.

Prompt
Rys. 1. Nowy wygląd znaku zachęty wraz z godziną.

Znak zachęty (prompt) jest kontrolowany przez specjalną zmienną środowiskową PS1 (właściwie PS1, PS2, PS3, PS4). Aby zmienić jego wygląd trzeba zmienić zawartość tej zmiennej. Na końcu pokazany będzie sposób jak zrobić, by po włączeniu nowego terminala ustawienia, które zmieniliśmy były widoczne (póki co będą działać tylko dla tego terminala, w którym tę zmienną edytujemy).

Aby edytować zmienną środowiskową musimy użyć polecenia export w sposób następujący.

$ export PS1='Wartości'

Zamiast Wartości wpisujemy pewien ciąg znaków, który ma zostać wyświetlony. Powłoka pozwala na to, by w miejsce Wartości wpisywać specjalne znaki, a mianowicie sekwencje ucieczek, które pozwalają, aby wyświetlany tekst prompt'a zmieniał się dynamicznie. Wszystkie sekwencje ucieczek zostały przedstawione poniżej.

Sekwencja ucieczkiOpis
\aDzwonek (ang. Bell) - znak ASCII (07)
\dData w formacie: Dzień tygodnia Miesiąc Dzień (np. "Tue May 13")
\D{format}Format jest przekazywany do strftime i zwrócony wynik wstawiany jest do prompt'a. Jeśli format był pusty, to rezultatem jest lokalna reprezentacja czasu. Nawiasy klamrowe są potrzebne.
\eZnak ucieczki ASCII (033) - Ważny znak!
\hNazwa komputera (hostname) - do pierwszego znaku '.'
\HNazwa komputera (hostname)
\jLiczba aktualnie zarządzanych operacji przez shell'a
\lPodstawowa nazwa urządzenia terminalowego
\nZnak nowej linii
\rPowrót karetki (ang. carriage return)
\sNazwa shella, podstawowa nazwa $0
\tAktualny czas w formacie 24-godzinnym (HH:MM:SS)
\TAktualny czas w formacie 12-godzinnym (HH:MM:SS)
\@Aktualny czas w formacie 12-godzinnym (am/pm)
\AAktualny czas w formacie 24-godzinnym (HH:MM)
\uNazwa aktualnego użytkownika
\vWersja basha (np. 2.00)
\VWydanie Basha, wersja + path level (np. 2.00.0)
\wŚcieżka dostępu do bieżącego katalogu. Jeśli bieżącym katalogiem jest $HOME to nazwa skracana jest do tyldy (~)
\WNazwa bieżącego katalogu. Jeśli bieżacym katalogiem jest $HOME to nazwa skracana jest do tyldy (~)
\!Numer (ilość, liczone względem historii) wykonanych poleceń
\#Numer (ilość) wykonanych poleceń
\$Jeśli efektywny UID jest 0 to znak: #, w przeciwnym wypadku znak: $
\nnnZnak przedstawiony za pomocą liczby ósemkowej (np. 033)
\\Backslash
\[Rozpocznij sekwencję nie drukowalnych znaków, które używane są do kontrolowania wyświetlanych informacji prompt'a
\]Zakończ sekwencję nie drukowalnych znaków

Zaznaczone pogrubioną czcionką sekwencje są ważne. Aby stworzyć takiego prompt'a jak pokazano na rysunku 1 musimy użyć sekwencji ucieczek. A więc wpisując poniższe polecenie dostaniemy wynik prawie taki sam (prawie, bo bez kolorów) jak wspomniany prompt z rysunku 1.

$ export PS1='[\A][\u@\h][\w] $ '

Stałymi ciągami znaków są nawiasy kwadratowe, które rozdzielają dynamicznie zmieniające się parametry (sekwencje ucieczek). Jak widać, nie ma w tym nic trudnego. Zamiast Wartości wpisujemy to co chcemy, by terminal wyświetlał. Sprawa lekko się komplikuje jeśli chcemy pokolorować prompt'a. Oczywiście wszystko jest też według pewnego schematu, lecz długość ostatecznego polecenia może nieco przerazić. Nie mniej jednak w tym miejscu opiszę jak się koloruje poszczególne elementy.

Aby rozpocząć kolorowanie musimy użyć specjalnego polecenia. Jako, że polecenie to jest ciągiem znaków, które nie będą wyświetlane na ekranie, to musimy skorzystać z sekwencji ucieczki, która otwiera sekwencję nie drukowalnych znaków. Po wprowadzeniu polecenia kolorowania, sekwencję znaków nie drukowalnych zamykamy! Następnie wpisujemy tekst, który ma zostać wydrukowany (w wybranym kolorze). Następnie otwieramy sekwencje dla nie drukowalnych znaków i wpisujemy polecenie kończące kolorowanie, oraz zamykamy sekwencję dla znaków nie drukowalnych.

Generalnie kolorowanie tekstu odbywa się w następującej formie:

\e[X;Ym TEKST_DO_KOLOROWANIA \e[m

Gdzie:

KolorX;Y
Black0;30
Blue0;34
Green0;32
Cyan0;36
Red0;31
Purple0;35
Brown0;33

X można zamienić z 0 na 1 w celu uzyskania jaśniejszej wersji koloru.

Skoro mamy już właściwie wszystko co trzeba, to można zacząć kolorować prompt'a. Zacznijmy najpierw od godziny. Lepiej będzie jeśli rozdziele to na części, bo całe polecenie jest dość obszerne i na pierwszy rzut oka jest nie do ogarnięcia.

\[\e[0;34m\]\A\[\e[m\]

Polecenie to jest zrobione według schematu, który został opisany. Ponieważ mamy włączyć kolorowanie, a polecenie kolorowania nie jest ciągiem drukowalnych znaków to musimy przed jego użyciem użyć sekwencji otwierającej nie drukowalne znaki (pierwsze dwa znaki na czerwono). Po włączeniu tego musimy zamknąć tę sekwencję (drugie dwa znaki na czerwono). Kolejnymi znakami są \A, co odpowiada za godzinę w formacie 24-godzinnym. Aby ten i tylko ten tekst był w tym kolorze jaki wybraliśmy (X;Y = 0;34) musimy zamknąć kolorowanie. Dlatego też otwieramy najpierw sekwencję znaków dla nie drukowalnych znaków (pierwsze dwa znaki na niebiesko), wpisujemy polecenie zamykające kolorowanie, oraz zamykamy sekwencję znaków nie drukowalnych (drugie dwa znaki na niebiesko).

Ponieważ każda z naszych części jest otoczona nawiasami kwadratowymi, to musimy je dodać, czyli polecenie powyższe po lekkiej modyfikacji wygląda następująco.

[\[\e[0;34m\]\A\[\e[m\]]

Analogicznie według tego samego schematu zrobione są kolejne części prompt'a. Całość prezentuje się następująco (spacje pomiędzy częściami zostały celowo wstawione, by pokazać, gdzie kończy się jedna część, a zaczyna druga).

[\[\e[0;34m\] \A \[\e[m\]] [\[\e[0;32m\] \u \[\e[m\] @ \[\e[0;36m\] \h \[\e[m\]] [\[\e[0;35m\] \w \[\e[m\]] $

Teraz, aby otrzymać takiego samego prompt'a jak na rysunku 1, wystarczy wpisać poniższe polecenie (prawda, że nie czytelne na pierwszy rzut oka?:)).

$ export PS1='[\[\e[0;34m\]\A\[\e[m\]][\[\e[0;32m\]\u\[\e[m\]@\[\e[0;36m\]\h\[\e[m\]][\[\e[0;35m\]\w\[\e[m\]] $ '

W momencie wyłączenia terminala i ponownym właczeniu, dostajemy domyślne ustawienia prompt'a. Tak więc, aby zachować te ustawienia i przy każdym włączeniu terminala mieć takie ustawienia jakie chcemy musimy edytować plik .bashrc, który znajduje się w katalogu domowym. Wpisz w konsoli.

$ cp ~/.bashrc ~/.bashrc2 && gedit ~/.bashrc

Znajdź linie

if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

i w miejsce PS1 wpisz definicję nowego prompt'a, czyli dla przypadku z rysunku 1, wpisz:

PS1='[\[\e[0;34m\]\A\[\e[m\]][\[\e[0;32m\]\u\[\e[m\]@\[\e[0;36m\]\h\[\e[m\]][\[\e[0;35m\]\w\[\e[m\]] $ '

Jeśli dalej nie masz kolorów prompt'a zajrzyj pod ten link. W informacjach o kolorach terminala znajdziesz odpowiedź.

Jak widać, w pliku .bashrc w miejscu rozpoczęcia kolorowania jest \033, zamiast \e, nie ma to różnicy czy użyjemy litery e, czy tej ósemkowej wartości.

Aby uzyskać jaśniejszy kolor czcionki, należy podczas definiowania koloru zamiast 0 wstawić 1. Tak więc np. zamiast koloru 0;34 wstawić 1;34. Na poniższym rysunku pokazane jest jak to wyglądało u mnie. Zdecydowanie bardziej wolę jaśniejsze kolory do prompt'a.

Prompt
Rys. 2. Nowy wygląd znaku zachęty wraz z godziną oraz jaśniejszą czcionką.

Some rights reserved 2010 - 2015 Artur Pyszczuk

| Strona Główna | Kontakt |