Bash – formatowanie wyświetlanego tekstu
Dziś pora na kolejny wpis z cyklu opisującego Bash, czyli jedną z najpopularniejszych powłok systemów uniksowych. Tym razem opiszę ciekawostkę, to znaczy sposób, w jaki możemy dodać możliwość generowania kolorowego i sformatowanego tekstu do konsoli. Zapraszam do lektury!
W jaki sposób Bash interpretuje informację o kolorze tekstu?
Odpowiadają za to sekwencje specjalnych znaków kontrolnych, które zawierają informację o kolorze tekstu. No, tak naprawdę to nie tylko o kolorze, ale też o innych atrybutach, jak np. podkreślenie, kursywa, pogrubienie, widoczność czy nawet możliwość migania! Jednak w jaki sposób podać interpreterowi sekwencję znaków kontrolnych? Należy zacząć od znaku ucieczki, który w Bashu możemy wyspecyfikować na trzy, równoważne sposoby:
- \e
- \033
- \x1B
Wszystkie one rozpoczną sekwencję znaków kontrolnych, jeśli podamy je na wejściu polecenia echo z włączoną obsługą interpretowania takich sekwencji (opcja -e):
echo -e "Jestem \e[31mczerwony\e[0m"
wyświetli na ekranie:
Jestem czerwony
Zastąpienie w tym poleceniu znaku “\e” dowolnym z “\033” i “\x1B” (zapis szesnastkowy) nie zmieni działania polecenia.
Należy zaznaczyć, że znaki kontrolne następują po znaku otwierającego nawiasu kwadratowego “[”, następnie mamy listę znaków kontrolnych, oddzielonych średnikiem “;”. W powyższym przykładzie występuje jedynie jeden znak kontrolny, “31”, oznaczający czerwony kolor tekstu, stąd brak średnika. Znak “m” kończy sekwencję znaków kontrolnych, która od tego momentu zaczyna obowiązywać. Konsekwencją tego jest fakt, że trzeba ją jawnie wyłączyć, resetując wyjście skryptu. Służy do tego znak kontrolny “0”, który musi być wstawiony jako sekwencja kontrolna, a więc “\e[0m”.
Jakie kolory obsługuje Bash?
To zależy 🙂 Oczywiście od konkretnie używanego terminala i jego konfiguracji. Podam wartości prawdziwe dla większości z będących obecnie w użyciu terminali, dokładne dane o obsługiwanej ilości kolorów oraz opcjach formatujących można znaleźć np. tutaj.
Zacznijmy od tego, że ustawiać możemy kolor tekstu oraz (niezależnie!) kolor tła tekstu. Dla koloru tekstu możliwości są następujące (16 kolorów podstawowych i jeden specjalny – “domyślny kolor tekstu”):
Kolor | Znak kontrolny | Sekwencja włączająca |
---|---|---|
Czarny | 30 | \e[30m |
Czerwony | 31 | \e[31m |
Zielony | 32 | \e[32m |
Żółty | 33 | \e[33m |
Niebieski | 34 | \e[34m |
Różowy (magenta) | 35 | \e[35m |
Cyjan | 36 | \e[36m |
Specjalny – domyślny kolor tekstu | 39 | \e[39m |
Jasny szary | 37 | \e[37m |
Ciemny szary | 90 | \e[90m |
Jasny czerwony | 91 | \e[91m |
Jasny zielony | 92 | \e[92m |
Jasny żółty | 93 | \e[93m |
Jasny niebieski | 94 | \e[94m |
Jasny różowy (magenta) | 95 | \e[95m |
Jasny cyjan | 96 | \e[96m |
Biały | 97 | \e[97m |
Z kolei dla kolorów tła mamy następujące możliwości (16 kolorów podstawowych i 1 specjalny – “domyślny kolor tła”), łatwo zapamiętać, że to dokładnie te same wartości co kolor tekstu, ale +10:
Kolor | Znak kontrolny | Sekwencja włączająca |
---|---|---|
Czarny | 40 | \e[40m |
Czerwony | 41 | \e[41m |
Zielony | 42 | \e[42m |
Żółty | 43 | \e[43m |
Niebieski | 44 | \e[44m |
Różowy (magenta) | 45 | \e[45m |
Cyjan | 46 | \e[46m |
Specjalny – domyślny kolor tekstu | 49 | \e[49m |
Jasny szary | 47 | \e[47m |
Ciemny szary | 100 | \e[100m |
Jasny czerwony | 101 | \e[101m |
Jasny zielony | 102 | \e[102m |
Jasny żółty | 103 | \e[103m |
Jasny niebieski | 104 | \e[104m |
Jasny różowy (magenta) | 105 | \e[105m |
Jasny cyjan | 106 | \e[106m |
Biały | 107 | \e[107m |
Pamiętajmy, że wszystkie z tych możliwości możemy wykorzystać za pomocą polecenia echo z włączoną flagą -e. Dodatkowo, możemy włączać je jednocześnie, co oznacza, że przykładowo:
echo -e "Jestem \e[43;31mczerwony na żółtym tle\e[0m"
wyświetli w terminalu:
Jestem czerwony na żółtym tle
Robi się ciekawie: dodatkowe opcje formatowania obsługiwane przez Bash!
Opcje te pozwalają na uzyskanie efektu “Wow!” wśród znajomych, choć należy zaznaczyć, że ich przesadne użycie łatwo doprowadzi do zmniejszenia czytelności niż jej poprawy 😉
Aby włączyć poszczególne opcje formatowania tekstu na wyjściu możemy użyć następujących znaków kontrolnych:
Opcja | Znak kontrolny | Sekwencja włączająca | Przykład |
---|---|---|---|
Pogrubienie tekstu (i rozjaśnienie jendocześnie) | 1 | \e[1m | Tekst |
Zacienienie | 2 | \e[2m | Tekst |
Kursywa | 3 | \e[3m | Tekst |
Podkreślenie | 4 | \e[4m | Tekst |
Miganie | 5 | \e[5m | Tekst |
Odwrócenie kolorów: tekstu i tła | 7 | \e[7m | Tekst |
Niewidoczność (przydatne dla haseł) | 8 | \e[8m |
Za pomocą tych samych znaków kontrolnych, ale z wartością powiększoną o 20 możemy resetować odpowiednie opcje formatowania:
Opcja | Znak kontrolny | Sekwencja resetująca |
---|---|---|
Resetowanie pogrubiania tekstu | 21 | \e[21m |
Resetowanie zacienienia | 22 | \e[22m |
Resetowanie kursywy | 23 | \e[23m |
Resetowanie podkreślenia | 24 | \e[24m |
Resetowanie migania | 25 | \e[25m |
Resetowanie odwrócenia kolorów: tekstu i tła | 27 | \e[27m |
Resetowanie niewidoczności | 28 | \e[28m |
Resetowanie wszystkich opcji formatowania | 0 | \e[0m |
Składając wszystkie wiadomości razem, możemy uzyskać super fancy efekt czerwonego tekstu, migającego rytmicznie na żółtym tle, pogrubionego i podkreślonego jednocześnie 🙂
echo -e "Jestem \e[1;3;4;5;43;31;3mczerwony, pogrubiony, zaciemniony, podkreślony i migam na żółtym tle :)\e[0m"
Powyższe polecenie przeniesie nas żywcem do lat ‘90, pamiętnych czasów wspaniałych animacji na stronach internetowych, tym razem w wersji terminalowej:
Jestem czerwony, pogrubiony, zaciemniony, podkreślony i migam na żółtym tle :)
Pro Tip numer 1: Wyświetlenie wszystkich kombinacji kolorów i formatowania!
Możemy ułożyć prosty skrypt Bash, dzięki któremu w prosty sposób wyświetlimy wszystkie możliwe kombinacje kolorów tekstu, tła i dodatkowych opcji formatowania. Zadanie zrealizować można za pomocą trzech, zagnieżdżonych pętli for:
Przedstawiony skrypt wyświetli wszystkie dostępne kombinacje kolorów i opcji formatowania, a efekt jego działania powinien przypominać ten z obrazka poniżej:
Możliwości formatowania i kolorowania tekstu w terminalu, efekt działania powyższego skryptu
Niech stracę! Pro Tip numer 2: rozszerzenie możliwości skryptu o formatowanie tekstu
Przypiszmy odpowiednie sekwencje znaków kontrolnych do zmiennych o znaczących nazwach:
Teraz możemy zdefiniować kolorowe znaczniki, proste do użycia w interfejsie skryptu:
Od teraz możemy używać odpowiednich znaczników w poleceniu echo:
Co wyświetli w terminalu:
[INFO] Informacja
[INPUT] Podaj wartość:
[OK] Wszystko w porządku!
[ERROR] Wiadomość o błędzie
Dla kompletności, możemy jeszcze użyć polecenia test, aby sprawdzić czy zapisujemy wynik spryptu do konsoli czy do pliku. W tym drugim przypadku możemy darować sobie kolory i formatowanie, ponieważ zostałyby one zapisane jako znane nam sekwencje kontrolne “\e[31m”, co zaciemniłoby wynik działania skryptu. Z zapisywaniem do pliku możemy mieć do czynienia np. w przypadku logowania działania skryptu:
Bash, terminal i kolory – podsumowanie
Jak pokazałem, możliwości formatowania wyjścia, nawet z poziomu skryptu Bash’a są całkiem spore. Uzależnione są one od programu, którego używamy jako terminal, jednak te przedstawione w dzisiejszym wpisie są dość uniwersalne i powszechnie dostępne. Teraz nic nie stoi na przeszkodzie, aby tworzyć nie tylko funkcjonalne, ale też cieszące oko interfejsy do naszych skryptów 🙂 Dzięki za przeczytanie i zapraszam do dyskusji w sekcji komentarzy!