Приглашение командной строки для администраторов Linux вещь, которая находится перед глазами гораздо чаще, чем, например, обои рабочего стола. Рекомендации по изменения цвета приглашения для отличия одного сервера от другого при работе по ssh существуют давно. Но есть способ сделать приглашение ещё более функциональным и удобным в использовании. Например, моё приглашение занимает целых 3 строки. Но это совсем не громоздко, как может показаться на первый взгляд. Попробуйте ввести в терминале вот эту команду:
export PS1="\[\e[0;36m\]┌──\[\e[0m\][ \[\e[0;33m\]\u\[\e[0m\]\[\e[0;32m\]@\[\e[0;36m\]\h\[\e[0m\] ] [ \[\e[0;36m\]\t\[\e[0m\] ]\n\[\e[0;36m\]├── \[\e[0;32m\]\w\[\e[0;36m\]\n\[\e[0;36m\]└>\[\e[0m\]"
Это временно изменит ваше приглашение на трёхстрочное и вы сможете попробовать его в деле. Сделайте пару переходов по каталогам. Оцените удобство «длинной» версии пути до текущего каталога у вас перед глазами. Понравилось? Тогда добро пожаловать в статью, там всё разложено по полочкам. Ну а если не понравилось, просто закройте терминал. После перезапуска восстановится ваше обычное приглашение командной строки.
Вводная информация
Приглашение командной строки определяется переменной среды PS1. Если ввести команду echo $PS1, можно увидеть текущую конфигурацию приглашения. В приглашении используются специальные макросы, вроде: \h-имя хоста или \t-текущее время. Однако, в сущности переменная просто определяет шаблон строки, которая выводится терминалом при переводе каретки на новую строку. Поэтому, мы можем внутри приглашения использовать команду перевода каретки, стандартные модификаторы bash для изменения цвета и даже символы юникода. При открытии нового окна терминала, оболочка загружает файл ~/.bashrc, в котором содержатся переменные окружения. Если мы поместим в конец файла строку, определяющую переменную PS1, то при запуске терминала переменная будет загружена в окружение и мы увидим модифицированное приглашение.
Цвет
Цвет строки в bash задаётся escape последовательностями, которые должны следовать перед строкой. Мониторы уже давно отображают цветов больше, чем человеческий глаз может различить, но в bash’е исторически существует поддержка всего восьми: Black, Red, Green, Yellow, Blue, Purple, Cyan. Последовательность задаётся с дополнительным модификатором, который определяет начертание символов и интенсивность цвета. Есть последовательность для изменения цвета фона за символами (только за символами, не всего терминала). Ещё есть специальный модификатор, отменяющий действие всех предыдущих. Если не завершить строку таким модификатором, изменение цвета затронет всю строку до конца. Для использования цветов в консоли удобно создать файлик в домашнем каталоге и назвать его, например, .bash_colors. В файлике мы зададим переменные с понятными названиями, упрощающими использование цветового выделения. Итак, создайте файл ~/.bash_colors и наполните его следующим содержимым:
# Сброс RstColor='\e[0m' # Text Reset # Обычные цвета Black='\e[0;30m' # Black Red='\e[0;31m' # Red Green='\e[0;32m' # Green Yellow='\e[0;33m' # Yellow Blue='\e[0;34m' # Blue Purple='\e[0;35m' # Purple Cyan='\e[0;36m' # Cyan White='\e[0;37m' # White # Жирные BBlack='\e[1;30m' # Black BRed='\e[1;31m' # Red BGreen='\e[1;32m' # Green BYellow='\e[1;33m' # Yellow BBlue='\e[1;34m' # Blue BPurple='\e[1;35m' # Purple BCyan='\e[1;36m' # Cyan BWhite='\e[1;37m' # White # Подчёркнутые UBlack='\e[4;30m' # Black URed='\e[4;31m' # Red UGreen='\e[4;32m' # Green UYellow='\e[4;33m' # Yellow UBlue='\e[4;34m' # Blue UPurple='\e[4;35m' # Purple UCyan='\e[4;36m' # Cyan UWhite='\e[4;37m' # White # Фоновые On_Black='\e[40m' # Black On_Red='\e[41m' # Red On_Green='\e[42m' # Green On_Yellow='\e[43m' # Yellow On_Blue='\e[44m' # Blue On_Purple='\e[45m' # Purple On_Cyan='\e[46m' # Cyan On_White='\e[47m' # White # Высоко Интенсивные IBlack='\e[0;90m' # Black IRed='\e[0;91m' # Red IGreen='\e[0;92m' # Green IYellow='\e[0;93m' # Yellow IBlue='\e[0;94m' # Blue IPurple='\e[0;95m' # Purple ICyan='\e[0;96m' # Cyan IWhite='\e[0;97m' # White # Жирные Высоко Интенсивные BIBlack='\e[1;90m' # Black BIRed='\e[1;91m' # Red BIGreen='\e[1;92m' # Green BIYellow='\e[1;93m' # Yellow BIBlue='\e[1;94m' # Blue BIPurple='\e[1;95m' # Purple BICyan='\e[1;96m' # Cyan BIWhite='\e[1;97m' # White # Высоко Интенсивные фоновые On_IBlack='\e[0;100m' # Black On_IRed='\e[0;101m' # Red On_IGreen='\e[0;102m' # Green On_IYellow='\e[0;103m' # Yellow On_IBlue='\e[0;104m' # Blue On_IPurple='\e[0;105m' # Purple On_ICyan='\e[0;106m' # Cyan On_IWhite='\e[0;107m' # White
А теперь мне нужно признаться: я обманщик. Такое объявление переменных не работает с многостраничным приглашением и вызывает неприятные «глюки». Я не знаю, почему это происходит и был бы рад, если бы вы рассказали мне об этом в комментариях. Ну а для того, что бы использовать цвета в приглашении командной строки, в описании этих escape последовательностей нужно добавить ещё один символ «[«. При этом в приглашении всё у вас будет хорошо, а вот при использовании этих переменных в при выводе в команде echo и другом подобном интерактиве, будет отображаться этот самый лишний символ. Итак, вот правильное содержимое файла с писанием цветов для использования в приглашении командной строки:
# Сброс RstColor='\[\e[0m\]' # Text Reset # Обычные цвета Black='\[\e[0;30m\]' # Black Red='\[\e[0;31m\]' # Red Green='\[\e[0;32m\]' # Green Yellow='\[\e[0;33m\]' # Yellow Blue='\[\e[0;34m\]' # Blue Purple='\[\e[0;35m\]' # Purple Cyan='\[\e[0;36m\]' # Cyan White='\[\e[0;37m\]' # White # Жирные BBlack='\[\e[1;30m\]' # Black BRed='\[\e[1;31m\]' # Red BGreen='\[\e[1;32m\]' # Green BYellow='\[\e[1;33m\]' # Yellow BBlue='\[\e[1;34m\]' # Blue BPurple='\[\e[1;35m\]' # Purple BCyan='\[\e[1;36m\]' # Cyan BWhite='\[\e[1;37m\]' # White # Подчёркнутые UBlack='\[\e[4;30m\]' # Black URed='\[\e[4;31m\]' # Red UGreen='\[\e[4;32m\]' # Green UYellow='\[\e[4;33m\]' # Yellow UBlue='\[\e[4;34m\]' # Blue UPurple='\[\e[4;35m\]' # Purple UCyan='\[\e[4;36m\]' # Cyan UWhite='\[\e[4;37m\]' # White # Фоновые On_Black='\[\e[40m\]' # Black On_Red='\[\e[41m\]' # Red On_Green='\[\e[42m\]' # Green On_Yellow='\[\e[43m\]' # Yellow On_Blue='\[\e[44m\]' # Blue On_Purple='\[\e[45m\]' # Purple On_Cyan='\[\e[46m\]' # Cyan On_White='\[\e[47m\]' # White # Высоко Интенсивные IBlack='\[\e[0;90m\]' # Black IRed='\[\e[0;91m\]' # Red IGreen='\[\e[0;92m\]' # Green IYellow='\[\e[0;93m\]' # Yellow IBlue='\[\e[0;94m\]' # Blue IPurple='\[\e[0;95m\]' # Purple ICyan='\[\e[0;96m\]' # Cyan IWhite='\[\e[0;97m\]' # White # Жирные Высоко Интенсивные BIBlack='\[\e[1;90m\]' # Black BIRed='\[\e[1;91m\]' # Red BIGreen='\[\e[1;92m\]' # Green BIYellow='\[\e[1;93m\]' # Yellow BIBlue='\[\e[1;94m\]' # Blue BIPurple='\[\e[1;95m\]' # Purple BICyan='\[\e[1;96m\]' # Cyan BIWhite='\[\e[1;97m\]' # White # Высоко Интенсивные фоновые On_IBlack='\[\e[0;100m\]' # Black On_IRed='\[\e[0;101m\]' # Red On_IGreen='\[\e[0;102m\]' # Green On_IYellow='\[\e[0;103m\]' # Yellow On_IBlue='\[\e[0;104m\]' # Blue On_IPurple='\[\e[0;105m\]' # Purple On_ICyan='\[\e[0;106m\]' # Cyan On_IWhite='\[\e[0;107m\]' # White
Теперь нужно загрузить переменные из файла командой source ~/.bash_colors. Посмотреть, как будет выглядеть текст можно командой echo c опцией -e:
Наконец, к главному
С цветами теперь всё стало понятно. Осталось разобраться с макросами и линиями, которые у меня соединяют строки приглашения. Начну с линий. Это обычные символы unicode, задуманные для рисования таблиц. Как можно заметить, я всего лишь использую символы:┌ , ─ , ├ ,└ и > . Расположив их соответствующим образом, я получил рисунок, который вы уже видели:
«Макросами» я называю служебные сокращения для вывода имени хоста, пользователя, текущего времени, рабочего каталога и т.д. Правильное их название: прерывания приглашения. Итак, этих прерываний не так уж и много:
\a символ ASCII bell (07)
\d дата в формате «День недели. месяц. день» (Чт. февр. 18)
\D{format} тоже дата, но поддерживается передача шаблона в формате strftime(3). Если шаблон пустой, используется шаблон локали.
\e символ ASCII escape (033) — используется для экранирования escape последовательностей (например, тех самых цветов)
\h короткий вариант имени хоста (без домена)
\H полное имя хоста
\j количество заданий, запущенных в текущем терминале
\l ID терминала
\n перевод каретки (переход на новую линию)
\r возврат каретки (выводить строку поверх)
\s имя оболочки (shell), значение переменной $0
\t текущее время в формате ЧЧ:ММ:СС 24 часа
\T текущее время в формате ЧЧ:ММ:СС 12 часов
\@ текущее время в формате ЧЧ:ММ с указанием до/после полудня (зависит от локали)
\A текущее время в формате ЧЧ:ММ
\u имя пользователя
\v версия оболочки
\V больше информации о версии
\w текущий рабочий каталог целиком, домашний каталог заменяется тильдой (~)
\W последняя часть пути рабочего каталога, домашний каталог заменяется тильдой (~)
\! номер последней введённой команды в истории
\# номер команды в текущей сессии
\$ символ заменяется на «#», если uid=0 (т.е. работает root) и остаётся «$» в остальных случаях
И, разумеется, никто не запрещает использовать вывод любой команды в приглашении. В том числе и вызов самописной функции. Я, например, написал функцию для вывода load average. Причём функция не просто выводит значения la, но и раскрашивает цифры в зависимости от значения. При превышении лимита цифры становятся красными. Итак, предлагаю создать файлик ~/.functions и вставить в него следующее содержимое:
#Значение la, при котором цифры станут красными let CRIT_LOAD=2 function load_average { # Load average set -- `cat /proc/loadavg` five=$1 let int_five=`echo $five | cut -d '.' -f1` ten=$2 let int_ten=`echo $ten | cut -d '.' -f1` fifteen=$3 let int_fifteen=`echo $fifteen | cut -d '.' -f1` #FIVE if [ $int_five -gt $CRIT_LOAD ]; then echo -ne "\e[0;31m" fi echo -n " $five" if [ $int_five -gt $CRIT_LOAD ]; then echo -ne "\e[0;33m" fi #TEN if [ $int_ten -gt $CRIT_LOAD ]; then echo -ne "\e[0;31m" fi echo -n " $ten" if [ $int_ten -gt $CRIT_LOAD ]; then echo -ne "\e[0;33m" fi echo -ne "\e[0;33m" #FIFTEEN if [ $int_fifteen -gt $CRIT_LOAD ]; then echo -ne "\e[0;31m" fi echo -n " $fifteen " if [ $int_fifteen -gt $CRIT_LOAD ]; then echo -ne "\e[0;33m" fi }
Обратите внимание, в функции я использую «голые» escape последовательности цветов, а не переменные. Дело в том, что файлик с функциями у меня большой и путешествует со мной по серверам. А вот файлик с определением переменных я за собой не таскаю.
Итак, осталось собрать всё вместе. Самое время открыть для редактирования файл ~/.bashrc и в конец файла добавить подключение файла с описанием цветов и файл с функциями:
source ~/.bash_colors source ~/.functions
И после этих строк, собственно, объявим переменную PS1. Например, как у меня:
PS1="$Cyan┌──$RstColor[ $Yellow\u$Green@$Cyan\h$RstColor ] [$Yellow $(load_average) $RstColor] $RstColor[ $Cyan\t$RstColor ]\n$RstColor$Cyan├── $Green\w\n$Cyan└>$RstColor"
Ну и как отмечалось ранее, можно добавить любые символы. Главное, что бы консольный шрифт их поддерживал: