Використання змінних для зберігання термінальних кольорових кодів для PS1?


33

У моєму .bashrcкольорі я використовую термінальні кольори ANSI для розфарбовування різних бітів. Це виглядає приблизно так:

PS1='\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$ '

де virtual_envі git_branchє bash функції, які виводять матеріал на stdout.

Тепер, щоб полегшити читання та зміни, я хотів би зберігати коди кольорів у змінних і посилатися на них, а не вбудовувати їх безпосередньо в PS1. Тож у мене є купа таких змінних:

GREEN="\[\033[32m\]"
YELLOW="\[\033[33m\]"
RESET="\[\033[0m\]"

Я хотів би мати можливість написати щось на кшталт:

PS1='\u@\h:\w${YELLOW}$(virtual_env)${GREEN}$(git_branch)${RESET}$ '

Але це не спрацьовує - кольорові коди відображаються у відповіді, як ніби вони втекли. Кольори працюють правильно, якщо я замість цього використовую подвійні лапки PS1, але підказка змінюється лише тоді, коли я це роблю source ~/.bashrc.

Я спробував інші речі , які я бачив , що люди роблять - використовуючи printf, використовуючи одиничні лапки для квітів, поміщаючи \[і \]в PS1замість змінного кольору, але нічого не схоже на роботу.

Як я можу використовувати змінні для кольорових кодів?


Ви можете дати нам своє .bashrc?
cuonglm

@cuonglm Всі ваші .bashrc належать нам? Я покажу себе.
CivFan

Відповіді:


20

Рішення полягає в тому, щоб отримати оболонку для заміни змінних кольорів при визначенні підказки, але не функцій. Для цього використовуйте подвійні лапки, як ви попередньо пробували, але уникайте команд, щоб вони не оцінювались до того моменту, як з'явиться запит.

PS1="\u@\h:\w${YELLOW}\$(virtual_env)${GREEN}\$(git_branch)${RESET}$ "

Зауважте, що \перед $()кожною командою.

Якщо ми це повторюємо, ми бачимо:

echo "$PS1"
\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$ 

Як бачимо, змінні кольорів були замінені, але не команди.


1
Схоже, це не працює, якщо $ (git_branch) також намагається друкувати за допомогою $ {YELLOW} і т. Д. У цьому розділі ви все одно отримаєте всі символи [].
WB Reed

7

Проблема полягає в тому, що ваша змінна GREENмістить буквальний рядок, що складається з "зворотної косої кути нахиленої риски нуля три три" тощо. Він не містить, наприклад, символу втечі ASCII, як потрібно, щоб ваш термінал змінив колір.

Ви можете вводити контрольні символи в GREENYELLOWта RESET) вручну, але набагато кращим варіантом є використання tputв першу чергу, щоб вам не потрібно було нічого жорстко кодувати і ви будете підтримувати будь-який тип терміналу.

GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
RESET="$(tput setaf 0)"

Причина, чому він вмикає, коли ви вводите «зворотну PS1косу рису нуль три три» тощо тощо, - це те, що інтерпретація певних послідовностей зворотної косої риси є ознакою спонукання bash (див. Розділ PROMPTING в посібнику. Ця заміна відбувається перед розширенням параметрів, командою заміщення, арифметичне розширення та видалення цитат, тому це не застосовується до результатів усіх інших операцій.


5
Роблячи це таким чином, вам потрібно загорнути змінні кольорів \[\]всередині $PS1. Наприклад: PS1='\u@\h:\w\[${YELLOW}\]'. Якщо ви цього не зробите, і закінчите довгу команду, яка переходить до наступного рядка, ви зіткнетеся з усілякими проблемами. Оболонка використовує, \[\]щоб визначити, які символи не друкуються, тому не враховує їх для обчислення підказки довжини. Це потрібно для того, щоб він міг правильно намалювати лінію, коли вона перевищує ширину клеми.
Патрік

Я не знав про це tput, дякую. Я зараз використовуватиму відповідь Патріка, але перегляну це, коли отримаю можливість.
Ісмаїл Бадаві

2

Змініть спосіб заповнення $ GREEN, $ YELLOW та $ RESET:

GREEN="$(echo -e "\033[32m")"
YELLOW="$(echo -e "\033[33m")"
RESET="$(echo -e "\033[0m")"

PS1='\u@\h:\w${YELLOW}$(virtual_env)${GREEN}$(git_branch)${RESET}$ '

1
Це фактично робить те саме, що відповідь Селади. Але Celada є більш портативним, якщо термінал використовує різні коди евакуації для налаштування кольору. Це також матиме те ж саме питання, що й у рядку, що підказує.
Патрік

2
У \[…\]біт повинен залишатися в запрошенні, ви не можете запхати його в змінної. Ви видалили його повністю, що призведе до проблем із відображенням (курсор не знаходиться в тому положенні, де очікує це баш).
Жил "ТАК - перестань бути злим"

Крім проблем @Patrick, echo -e не є портативним.
helpermethod

1
Завдяки непереносимості надається більше функцій - tput setafне дозволяє вибирати "легкий" набір кольорів, наприклад, світло-блакитний. @ Кіра відповідь, однак, так і є.
CivFan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.