Русский
Русский
English
Статистика
Реклама

Красные глаза


Привет, представляю вашему вниманию небольшой туториал по оформлению приглашения командной строки с эффектом красных глаз.

Все кто работал в консоли какого-нибудь Линукса наверно отмечали удобную особенность отображать текущую папку, имя пользователя, имя сервера и что-то еще в зависимости от дистра в строке приглашения. Мне тоже это всегда нравилось. Но иногда получалось вот так:


Сложно творить в строке из трех символов, конечно курсор переходит на следующую строку но это скорей еще больше бесит чем помогает. И вот в какой-то момент я сказал себе:


Я решил вернуть себе все пространство командной строки и больше не отдавать никому и никогда. Встал вопрос, как изменить текст приглашения командной строки? Оказалось, очень просто, достаточно изменить специальную системную переменную `PS1`.


Да, прямо в терминале можно задать новый текст приглашения. Но как сохранить изменения? Да и без информации о текущем каталоге как-то неуютно себя чувствуешь, постоянно задаешь себе вопрос: Где я? Поможет файл ~/.bashrc, в нём можно сохранить изменение PS1, а чтобы информация о текущей директории не занимала рабочее пространство, я решил разместить её не В а НАД командной строкой. Добавим в файл ~/.bashrc строку:
PS1='$PWD\n# '

Обратите внимания на одинарные кавычки, если мы используем двойные, то вместо указателя на переменную $PWD (системная переменная, в которой храниться полный путь текущей папки, аналог команда pwd) в строку приглашения запишется ее значение(текущий каталог) и меняться при переходе из папки в папку не будет. Выглядит это так:


Командная строка полностью свободна, но имя папки сливается с содержимым если выполнить команду ls. Придется отделить мух от котлет имя папки от содержимого. Я решил добавить рамки для $PWD, добавив сверху и снизу строки из символов "-". Как узнать количество символов в строке? Для этого тоже есть системная переменная $COLUMNS. А чтобы быстро сформировать строку с необходимым количеством символов "-" воспользуемся командой printf:
printf -v line "%${COLUMNS}s"

Эта команда создаст переменную $line и заполнит её пробелами в количестве $COLUMNS но нам нужны не пробелы а "-", для этого используем следующий трюк:
line=${line// /-} # заменить все пробелы на -

Добавим этот код в ~/.bashrc
printf -v line "%${COLUMNS}s"line=${line// /-}PS1='\n$line\n$PWD\n$line\n# '



Отлично, но если сейчас изменить размер окна терминала, размер линий не изменится и красота пропадет:


Чтобы поправить ситуацию перенесем новый код в функцию info и добавим её в PS1:
info () {    printf -v line "%${COLUMNS}s"    line=${line// /-}    printf "\n$line\n$PWD\n$line\n# "}PS1='$(info)'

Можно совместить приятное с полезным, добавив в верхний ограничитель вставку с именем хоста. Вставка с именем будет посередине, для этого нам необходимо вычислить центр линии(с учетом длинны названия хоста и доп. символов):
info () {    name_lenght="{ $HOSTNAME }"    name_lenght=${#name_lenght}    top_line_left=$[(COLUMNS-name_lenght)/2]    top_line_right=$[COLUMNS-(top_line_left+name_lenght)]    printf -v top_line "%${top_line_left}s{_S_${HOSTNAME}_S_}%${top_line_right}s"    printf -v bot_line "%${COLUMNS}s"    bot_line=${bot_line// /-}    top_line=${top_line// /-}    top_line=${top_line//_S_/ }    printf "\n$top_line\n$PWD\n$bot_line\n# "}PS1='$(info)'



Я заключил имя хоста в фигурные скобки с пробелами, но вместо пробелов вокруг $HOSTNAME используются символы "_S_" которые затем меняются на пробелы. Это необходимо потому, что в итоговой строке все пробелы заменяются на "-", а внутри вставки должны остаться пробелы. Добавим красок, для этого подготовим переменные с кодами изменения цвета текста в терминале, я использовал такие цвета:
RED='\e[31m' # красныйGRN='\e[32m' # зелёныйYLW='\e[33m' # жёлтыйBLU='\e[34m' # синийMGN='\e[35m' # пурпурныйDEF='\e[0m'  # вернуть значения по умолчаниюBLD='\e[1m'  # жирноDIM='\e[2m'  # тускло

Добавим эти переменные в наш код:
info () {    name_lenght="{ $HOSTNAME }"    name_lenght=${#name_lenght}    top_line_left=$[(COLUMNS-name_lenght)/2]    top_line_right=$[COLUMNS-(top_line_left+name_lenght)]    printf -v top_line "%${top_line_left}s{_S_$DEF$BLD$HOSTNAME${DEF}_S_$GRN}%${top_line_right}s"    printf -v bot_line "%${COLUMNS}s"    bot_line=$GRN${bot_line// /-}$DEF    top_line=${top_line// /-}    top_line=$GRN${top_line//_S_/ }$DEF    printf "\n$top_line\n$BLD$BLU$PWD$DEF\n$bot_line\n# "}PS1='$(info)'



Идем дальше, правая часть выглядит пусто, можно разместить там дату, и время:
printf -v date "%(%a %d %b %T)T"

Чтобы разместить это справа необходимо добавить какое-то количество пробелов после $PWD, какое, давайте посчитаем:
center_space=$[COLUMNS-${#date}-${#PWD}]((center_space<0)) && center_space=1...printf "\n$top_line\n$BLD$BLU$PWD$DEF%${center_space}s$DIM$date\n$bot_line\n# "



Можно ли сделать лучше? Конечно, добавим вывод git status если находимся в папке с git проектом:
    git_tst= git_clr=    [[ -d .git ]] && {        git_tst=(GIT $(git status -sb))        git_tst="${git_tst[*]} " # простой для теста        git_clr=(GIT $(git -c color.ui=always status -sb))        git_clr="${git_clr[*]} " # цветной для вывода    }    ...    center_space=$[COLUMNS-${#date}-${#PWD}-${#git_tst}]    ...    printf "\n$top_line\n$BLD$BLU$PWD$DEF%${center_space}s${git_clr[*]}$DIM$date\n$bot_line\n\$ "



Обратите внимания что git_clr и git_tst сначала записываются массивом, а затем преобразуются в переменные. Это необходимо для того чтобы удалить переходы строки из вывода git status. Но где же глаза? Сейчас будут глаза О_о, создадим массив с базовым набором глаз:
eyes=(O o    )

И посчитаем их количество:
en=${#eyes[@]}

Добавим символ рта:
mouth='_'

И сделаем генератор случайных морд:
face () {    printf "$YLW${eyes[$[RANDOM%en]]}$mouth${eyes[$[RANDOM%en]]}$DEF"}

Глаза будут находиться по краям информационного поля, необходимо учесть их при расчете количества пробелов в середине, подготовим для этого отдельную переменную:
face_tst='O_o  o_O'...center_space=$[COLUMNS-${#date}-${#PWD}-${#git_tst}-${#face_tst}]printf "\n$top_line\n$(face) $BLD$BLU$PWD$DEF%${center_space}s$git_clr$DIM$date $(face)\n$bot_line\n\$ "



Как заставить глаза покраснеть? Долго сидеть за компом, не спать На stackoverflow.com мне попался интересный вопрос, автор спрашивает: как менять цвет в приглашении командной строки на красный если последняя команда завершилась неудачно? Это и натолкнуло меня на идею красных глаз. Добавим в функцию info запоминание статуса завершения последней команды:
info () {    error=$?    ...}

И изменим функцию face таким образом, чтобы она проверяла переменную $error и в зависимости от её значения красила глаза в красный или жёлтый:
face () {    [[ $error -gt 0 ]] && ecolor=$RED || ecolor=$YLW    printf "$ecolor${eyes[$[RANDOM%en]]}$YLW$mouth$ecolor${eyes[$[RANDOM%en]]}$DEF"}



Ну вот у меня глаза покраснели, но можно добавить еще кое-что. Добавим проверку переменной $debian_chroot:
[[ $debian_chroot ]] && chrt="($debian_chroot)" || chrt=...name_lenght="{ $HOSTNAME$chrt }"...printf -v top_line "%${top_line_left}s{_S_$DEF$BLD$HOSTNAME$chrt${DEF}_S_$GRN}%${top_line_right}s"

И изменим текст в заголовке окна терминала:
PS1='$(info)'; case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;$(face 1) \w\a\]$PS1";; esac

В заголовок будет выводится морда и текущий каталог, но придется немного доработать функцию face чтобы она рисовала морду без цветовых кодов, они в заголовке бутут отображаться просто текстом, передадим функции face какой-нибудь параметр (например 1), внутри функции добавим проверку, если задан 1-й аргумент, выдать морду без разукрашивания:
face () {    [[ $error -gt 0 ]] && ecolor=$RED || ecolor=$YLW    [[ $1 ]] && printf "${eyes[$[RANDOM%en]]}$mouth${eyes[$[RANDOM%en]]}" \             || printf "$ecolor${eyes[$[RANDOM%en]]}$YLW$mouth$ecolor${eyes[$[RANDOM%en]]}$DEF"}



Итоговый скрипт:
RED='\e[31m' # красныйGRN='\e[32m' # зелёныйYLW='\e[33m' # жёлтыйBLU='\e[34m' # синийMGN='\e[35m' # пурпурныйDEF='\e[0m'  # вернуть значения по умолчаниюBLD='\e[1m'  # жирноDIM='\e[2m'  # тусклоeyes=(O o    ) en=${#eyes[@]} mouth='_'face () {    [[ $error -gt 0 ]] && ecolor=$RED || ecolor=$YLW    [[ $1 ]] && printf "${eyes[$[RANDOM%en]]}$mouth${eyes[$[RANDOM%en]]}" \             || printf "$ecolor${eyes[$[RANDOM%en]]}$YLW$mouth$ecolor${eyes[$[RANDOM%en]]}$DEF"}info () { error=$? git_tst= git_clr=    [[ -d .git ]] && {        git_tst=(GIT $(git status -sb))        git_tst="${git_tst[*]} " # простой для теста        git_clr=(GIT $(git -c color.ui=always status -sb))        git_clr="${git_clr[*]} " # цветной для вывода    }    [[ $debian_chroot ]] && chrt="($debian_chroot)" || chrt=    name_lenght="{ $HOSTNAME$chrt }"    name_lenght=${#name_lenght}    face_tst='O_o  o_O'    top_line_left=$[(COLUMNS-name_lenght)/2]    top_line_right=$[COLUMNS-(top_line_left+name_lenght)]    printf -v top_line "%${top_line_left}s{_S_$DEF$BLD$HOSTNAME$chrt${DEF}_S_$GRN}%${top_line_right}s"    printf -v bot_line "%${COLUMNS}s"    printf -v date  "%(%a %d %b %T)T"    top_line=${top_line// /-}    top_line=$GRN${top_line//_S_/ }$DEF    bot_line=$GRN${bot_line// /-}$DEF    center_space=$[COLUMNS-${#date}-${#PWD}-${#git_tst}-${#face_tst}]    ((center_space<0)) && center_space=1    printf "\n$top_line\n$(face) $BLD$BLU$PWD$DEF%${center_space}s$git_clr$DIM$date $(face)\n$bot_line\n\$ "}PS1='$(info)'; case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;$(face 1) \w\a\]$PS1";; esac

На этом все, спасибо за внимание!) Подписывайтесь, ставьте лайки, вот это вот все, проект есть в гитхабе info-bar Творите, выдумывайте, пробуйте!)
проверка внимательности
Вы заметили в какой момент символ "#" в строке приглашения поменялся на "$"?)
Источник: habr.com
К списку статей
Опубликовано: 29.07.2020 22:04:59
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Кодобред

Bash

Tutorial

Cli

Redeyes

Категории

Последние комментарии

© 2006-2021, personeltest.ru