W moim przypadku .bashrc
używam kodów kolorów terminala ANSI do kolorowania różnych bitów. To wygląda tak:
PS1='\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$ '
gdzie virtual_env
i git_branch
są funkcjami bash, które wypisują rzeczy na standardowe wyjście.
Teraz, aby ułatwić czytanie i modyfikację, chciałbym przechowywać kody kolorów w zmiennych i odwoływać się do nich, zamiast osadzać je bezpośrednio w PS1
. Mam więc kilka takich zmiennych:
GREEN="\[\033[32m\]"
YELLOW="\[\033[33m\]"
RESET="\[\033[0m\]"
Chciałbym móc napisać coś takiego:
PS1='\u@\h:\w${YELLOW}$(virtual_env)${GREEN}$(git_branch)${RESET}$ '
Ale to nie działa - kody kolorów wyświetlają się w monicie, jakby uciekły. Kolory działają poprawnie, jeśli zamiast nich używam podwójnych cudzysłowów PS1
, ale wówczas monit zmienia się tylko wtedy, gdy to robię source ~/.bashrc
.
Próbowałem innych rzeczy Widziałem ludzi zrobić - używając printf
przy użyciu apostrofów dla kolorów, strzelaj \[
i \]
we PS1
zamiast zmiennej barwy, ale nic nie wydaje się do pracy.
Jak mogę używać zmiennych dla kodów kolorów?
źródło
.bashrc
?Odpowiedzi:
Rozwiązaniem jest skłonienie powłoki do zastąpienia zmiennych kolorów podczas definiowania monitu, ale nie funkcji. Aby to zrobić, użyj podwójnych cudzysłowów, tak jak pierwotnie próbowałeś, ale unikaj poleceń, aby nie były oceniane, dopóki nie zostanie narysowany monit.
Zwróć uwagę na
\
przed$()
każdym poleceniem.Jeśli to powtórzymy, zobaczymy:
Jak widać zmienne kolorów zostały podstawione, ale nie polecenia.
źródło
Problem polega na tym, że twoja zmienna
GREEN
zawiera dosłowny ciąg znaków składający się z „odwrotnego nawiasu ukośnego zero trzy trzy trzy” i tak dalej. Nie zawiera na przykład znaku zmiany znaczenia ASCII wymaganego do zmiany koloru terminala.Można umieścić znaki sterujące w
GREEN
(aYELLOW
, aRESET
) ręcznie, ale o wiele lepszym rozwiązaniem jest użycietput
w pierwszej kolejności, tak aby nie trzeba ciężko kodem cokolwiek i będzie obsługiwać dowolny typ terminala.Powodem, dla którego pojawia się na świecie po umieszczeniu „odwrotnego ukośnika zero trzy trzy” itd.… Bezpośrednio,
PS1
jest to, że interpretacja niektórych sekwencji odwrotnego ukośnika jest cechą monitowania basha (zobacz sekcję PROMPTING w instrukcji. Podstawienie to następuje przed rozwinięciem parametru, polecenie podstawianie, interpretacja arytmetyczna i usuwanie cytatów, więc nie jest stosowane do wyników wszystkich innych operacji.źródło
\[\]
wewnątrz$PS1
. Na przykład:PS1='\u@\h:\w\[${YELLOW}\]'
. Jeśli tego nie zrobisz, a skończy się na długim poleceniu, które zawinie do następnego wiersza, napotkasz różnego rodzaju problemy. Powłoka używa\[\]
do określenia, które znaki nie są drukowalne, więc nie uwzględnia ich w obliczeniach długości pytania. Potrzebuje tego, aby mógł poprawnie narysować linię, gdy przekroczy szerokość terminala.tput
. Na razie skorzystam z odpowiedzi Patricka, ale wrócę do niej, kiedy będę miał szansę.Zmień sposób wypełniania $ ZIELONY, $ ŻÓŁTY i $ RESET:
źródło
\[…\]
potrzeby bitowe pozostać w wierszu poleceń nie można nadziać ją w zmiennej. Usunąłeś go całkowicie, co spowoduje problemy z wyświetlaniem (kursor nie znajduje się w pozycji, w której oczekuje bash).tput setaf
nie pozwala wybierać z „jasnego” zestawu kolorów, takich jak jasnobłękitny. Odpowiedź @ Cyrusa tak jest.