Как стать автором
Обновить

Комментарии 46

НЛО прилетело и опубликовало эту надпись здесь
Дело не в bash. Эти ESC последовательности команд зашитые в PS1 читаются терминалом и терминал, а не bash их расцвечивает. Так что будут работать с любым шелом. И чем еще удобен так то что при этом на сам терминал не завязано. Будешь в одном терминале переходить по ssh с сервера на сервер и цвета у приглашения будут меняться соответственно. Ну и цвет курсора, когда открыты конфиги в редакторе, например, беглово взгляда на курсор достаточно чтобы не забывать — на каком сервере.
НЛО прилетело и опубликовало эту надпись здесь
Разумеется конфиги (.bashrc или что там у вас) должны быть на каждом сервере, каждый в свой цвет. Сами по себе цвета не появятся. :) Аналог PS1 у fish устроен по другому, там это функция fish_prompt. Но суть та же самая, если будите там выдывать ESC последовательности управляющие цветом — они будут интерпретироваться терминалом. Шелл только принимает символы и выдает их, в том числе ESC последовательности и прочие управляющие символы, а цвета воспроизводит всегда терминал.

Bash тоже в линукс консоле работает. Но цвета линукс консоле цвета по беднее и их по другому надо будет задавать, цвет курсора там задать не получилось и набор цветов там будет упрощенный.
НЛО прилетело и опубликовало эту надпись здесь
в плане автодополнения путей вот еще удобная штука github.com/rupa/z
А так же больше цветов, еще больше!
git config --global color.ui true
alias ls='ls --color=auto'
alias dmesg='dmesg --color=always'
alias grep='grep --color=always'
alias fgrep='fgrep --color=always'
alias egrep='egrep --color=always'
alias gcc='gcc -fdiagnostics-color=always'
alias pacman='pacman --color=always'
А, еще можно man раскрасить:

man() {
    env LESS_TERMCAP_mb=$'\E[01;31m' \
    LESS_TERMCAP_md=$'\E[01;38;5;74m' \
    LESS_TERMCAP_me=$'\E[0m' \
    LESS_TERMCAP_se=$'\E[0m' \
    LESS_TERMCAP_so=$'\E[38;5;246m' \
    LESS_TERMCAP_ue=$'\E[0m' \
    LESS_TERMCAP_us=$'\E[04;38;5;146m' \
    man "$@"
}
НЛО прилетело и опубликовало эту надпись здесь
Ну да, у меня практический тоже самое, только без load, одинаково мыслим. :) Но все это, в принципе, в одну строчку помещается, так что двухстрочного для меня достаточно. Да и удобно еще тем что наглядно отделяет вывод одной команды от другой.
Во всем этом деле с датой расстраивает то, что время пишется на момент приглашения. Получить бы время выполнения))
Ну так если работаешь непрерывно, то по разнице времени на «момент приглашения» (т.е. на момент завершения задачи) с предыдущим промптом можно приблизительно оценить время выполнения. А для более точной оценки есть команда time:
14:09:35 j0 olleg@petrel:~
$ time sleep 10

real	0m10.009s
user	0m0.000s
sys	0m0.000s
14:09:51 j0 olleg@petrel:~
$ 
Как-то я не подумал про следующее приглашение. Действительно, задачи как правило выполняются меньше секунды, редко больше 5 секунд. Этой оценки вполне хватит.
Пойду подпиливать .bashrc
Извините, я всех запутал с терминологией, меня интересовало именно время начала исполнения. Но длительность выполнения тоже стоит взять на вооружения.
Спасибо за идею, попробую. И splarv тоже спасибо за статью!
НЛО прилетело и опубликовало эту надпись здесь
cat /proc/loadavg | awk '{print $2}' — LA5
НЛО прилетело и опубликовало эту надпись здесь
А по-моему, двухстрочное приглашение — монстроузное приглашение, а вся выведенная информация избыточна и выводится либо средствами оконного менеджера (часы), либо не шибко полезна, чтобы постоянно висеть перед глазами (loadavg).

Для себя я подобрал оптимальную конфигурацию: hostname, текущий каталог с сокращением до половины ширины терминала и информация о свободном месте на текущей файловой системе.
а если оконного менеджера нет?
у меня выводится свободная память, время, текущий каталог и количество задач в бекграунде
но это, конечно, вкусовщина
>а если оконного менеджера нет?

Когда я подключаюсь по ssh, всегда использую tmux или screen (на совсем уж древних системах). Отложенные и возобновленные сессии — это очень удобно, плюс мультиплексор имеет свой персональный статусбар, куда можно вывести часики и имя хоста.

Но если уж вот прям никак: мультиплексор нельзя, оконного менеджера нет, кругом только чОрная консоль, то проще набрать три буковки команды top или четыре команды date, чем постоянно держать перед глазами мусор, который, к слову, не будет автоматически обновляться.

Помнится, раньше было очень модно городить conky и выводить туда такую «полезную» информацию, как версия ядра, хостнейм своего локалхоста, несколько штук часов, календарик… Это вот все напоминает.
Даже такой минимум как хостнейм и текущий каталог (а это по умолчанию) порой занимают порядочную ширину и для набора команд остается недостаточно места. Да и неудобно это. Гораздо приятнее набирать команды с абсолютно пустой строки. :) Это и было основной причиной двухстрочного приглашения. Плюс оно удобно отделяет вывод предыдущей команды. А вывод времени в основном используется не для того чтобы знать текущее время, а для того чтобы понимать насколько какая программа «подвисла», сколько выполняется длительная компиляция и т.д. Я понимаю что time удобнее. Но подобный интерес зачастую возникает не заранее, а после того как программа неожиданно долго работает. :) Так что у меня почти тоже что и у вас, разве что вывода свободного места нет, т.к. набрать df всегда просто.
>Даже такой минимум как хостнейм и текущий каталог (а это по умолчанию) порой занимают порядочную ширину

Потому, я обычно делаю вот так:
local DIRWIDTH
(( DIRWIDTH = ${COLUMNS} / 3 ))
local CUR="[ %$DIRWIDTH<..<%~%<< ]"
PROMPT="$DARK_GREEN$CUR$DEFAULT ->"


Путь срезается до трети ширины терминала. Вот двустороннее приглашение я люблю: справа у меня и выводится
df -hP .|sed -n '2p'|awk -F' ' '{print $4}' 

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

удобно, чтобы отличать один проект от другого
А вот это интересно. Про вывод картинок в терминале я не слышал. :)
Потому что это не картинки, а unicode символы. Другое дело, нужно, что бы баш их умел правильно «рисовать».
Не баш, а терминал. Должна быть или специальная поддержка со стороны терминала, чтобы он вставлял туда картинки. Либо их должен поддерживать системный фонт. Оказалось что в dejavu есть много смайликов и даже смайлики-котята. Можно использовать в терминале. :)
Да.
А во времена UNIXов, когда еще на было BASH и LINUX украшали экран ESC-последовательносями
больше десяти лет назад в хакере нашёл себе хороший, годный вариант оформления командной строки
get_freemem ()
{
echo -n `free | grep Mem | awk '{print $4}'`
}

export PS1="=(\w)=(\t)=("'`get_freemem`'")=(\j:\$?)=\n=>"

https://habrastorage.org/files/5b1/973/fb9/5b1973fb906a459492e70cab0c397b97.png
Проиллюстрирую, раз вы с отрицательной кармой:

image
$(ERR="$?"; if [[ "$ERR" != "0" ]]; then printf "\033[01;37m(%.*s)\033[00m " $ERR $ERR; fi) $PS1
добавляет код ошибки, белым в скобках, в начале PS1
Я сторонник минимализма в отношении подсказки, но у меня сохраняется расширенная история. Вот фрагмент .bashrc:

HISTTIMEFORMAT='%t%F %T%t'
echo $PROMPT_COMMAND|grep -q bash_eternal_history || export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND; } history -a; "'echo -e $?\\t$USER\\t$HOSTNAME\\t$PWD\\t"$(history 1)" >> ~/.bash_eternal_history'
Добавлю свои 5 копеек. Добавляет текущую ветку для репозитория. Для git и hg репозиториев.
image

hg_branch() {
    BRANCH=`hg branch 2> /dev/null | awk '{print "(hg:"$1")"}'`
    if [[ $BRANCH == *release* ]]
    then
        BRANCH="\e[31m$BRANCH"
    fi
    if [[ $BRANCH == *default* ]]
    then
        BRANCH="\e[31m$BRANCH"
    fi
    echo -e $BRANCH
}

в PS1:
$(__git_ps1 "(git:%s)")$(hg_branch)


ps: условия в hg_branch() раскрашивают блок в красный цвет, чтобы видно было, что не надо ничего коммитить в default и release
256 цветов в терминале — прошлый век. Большинство современных терминалов имеют поддержку 16 миллионов цветов (True Color). Вот здесь я собрал список терминалов, которые их поддерживают, и не поддерживают. Для большинства тех, которые не поддерживают — есть сторонние патчи или форки. Ведется работа по интеграции их в мэйнстрим. Есть даже Pull Request в tmux github.com/tmux/tmux/pull/112
Вроде оно логично, но нафига вам оттенки цвета «бедра испуганной нимфы»? По большому счету тут будут использоваться только чистые сатурированные тона, как правило. Красный, синий, желтый, зеленый… Человеческий мозг не в состоянии удержать даже 256 категорий одновременно. Что там может быть? Продакшен, тестовый нестабильный, тестовый предпродакшен и т.п. Ну 10 категорий. Дальше смысл теряется, на мой взгляд.
Вот это интересно, если оно так. У вас значится что Gnome Terminal тоже поддерживает. Напишите пример с echo который бы позволил задать цвет текста в 24хбитном RGB. Ваш пример по ссылке пробовал — не работает.
В gist-е упомянуто, что это применимо только к Gnome Terminal скомиленным Gtk+3, и libvte старше 0.36 версии.
Раз пошла такая пьянка, моя строка выглядит так:



Доступно в моём zsh-config репе: prompt.zsh

Выводит:

1) текущий каталог, если слишком длинный, то последние 5 каталогов,
2) текущая git-ветка, если я в репозитории (иначе не выводит этот компонент), вопросительный знак если есть незакоммиченные изменения, восклицательный — если есть изменения в стейджинге,
3) текущий терминал (удобно различать в каком терминале находишься и какой шелл убивать если что),
4) если команда выполнялась дольше 5 секунд, выводит сколько времени она выполнялась,
5) если команда неудачно завершилась, то выводит код ошибки.

Итого всё очень минималистично, выводит только ту информацию, которая важна по контексту, что позволяет держать строку очень короткой, но при этом информативной.

И да, для bash придётся переписать, но тут главное идея.
Вообще, мне больше нравится разыернутый синтаксис. Ненавижу перлообразные нагромождения, для меня они нечитаемы. Пример из Арчевики:
set_prompt () {
    Last_Command=$? # Must come first!
    Blue='\[\e[01;34m\]'
    White='\[\e[01;37m\]'
    Red='\[\e[01;31m\]'
    Green='\[\e[01;32m\]'
    Reset='\[\e[00m\]'
    FancyX='\342\234\227'
    Checkmark='\342\234\223'

    # Add a bright white exit status for the last command
    PS1="$White\$? "
    # If it was successful, print a green check mark. Otherwise, print
    # a red X.
    if [[ $Last_Command == 0 ]]; then
        PS1+="$Green$Checkmark "
    else
        PS1+="$Red$FancyX "
    fi
    # If root, just print the host in red. Otherwise, print the current user
    # and host in green.
    if [[ $EUID == 0 ]]; then
        PS1+="$Red\\h "
    else
        PS1+="$Green\\u@\\h "
    fi
    # Print the working directory and prompt marker in blue, and reset
    # the text color to the default.
    PS1+="$Blue\\w \\\$$Reset "
}
PROMPT_COMMAND='set_prompt'
Да я тоже за развернутый синтаксис. :) Но создать переменные для всех 255 цветов… (причем и для обозначений цвета для букв и для курсора, т.е. 510). Там даже уникальные имена цветам замучаешься придумывать, а когда придумаешь — забудешь какой конкретный цвет они обозначают. :)
А нафига вам 256 цветов? Я вообще смысла не вижу больше 10-15 использовать. Как писал уже выше, вы категории не запомните. Ну не может человеческий мозг разбивать множество на 100-200 категорий. Сводим к 3-5 обычно.
Вы правы, я использую ровно 5. Но выбирал то я тх из 255. :) Я за свободу выбора.

Скрипт не мой, где взял — не помню. Но огромное человеческое спасибо автору за это.


#!/bin/bash

#------------------------------------------------------------------------------+
#Color picker, usage: printf ${BLD}${CUR}${RED}${BBLU}"Hello!)"${DEF}          |
#-------------------------+--------------------------------+-------------------+
#       Text color        |       Background color         |                   |
#-----------+-------------+--------------+-----------------+                   |
# Base color|Lighter shade| Base color   | Lighter shade   |                   |
#-----------+-------------+--------------+-----------------+                   |
BLK='\e[30m'; blk='\e[90m'; BBLK='\e[40m'; bblk='\e[100m' #| Black             |
RED='\e[31m'; red='\e[91m'; BRED='\e[41m'; bred='\e[101m' #| Red               |
GRN='\e[32m'; grn='\e[92m'; BGRN='\e[42m'; bgrn='\e[102m' #| Green             |
YLW='\e[33m'; ylw='\e[93m'; BYLW='\e[43m'; bylw='\e[103m' #| Yellow            |
BLU='\e[34m'; blu='\e[94m'; BBLU='\e[44m'; bblu='\e[104m' #| Blue              |
MGN='\e[35m'; mgn='\e[95m'; BMGN='\e[45m'; bmgn='\e[105m' #| Magenta           |
CYN='\e[36m'; cyn='\e[96m'; BCYN='\e[46m'; bcyn='\e[106m' #| Cyan              |
WHT='\e[37m'; wht='\e[97m'; BWHT='\e[47m'; bwht='\e[107m' #| White             |
#--------------------------------------------------------------------+---------+
# Effects                                                                      |
#------------------------------------------------------------------------------+
DEF='\e[0m'   #Default color and effects                                       |
BLD='\e[1m'   #Bold\brighter                                                   |
DIM='\e[2m'   #Dim\darker                                                      |
CUR='\e[3m'   #Italic font                                                     |
UND='\e[4m'   #Underline                                                       |
INV='\e[7m'   #Inverted                                                        |
COF='\e[?25l' #Cursor Off                                                      |
CON='\e[?25h' #Cursor On                                                       |
else
#------------------------------------------------------------------------------+

Для использования в .bashrc нужно его "засорсить": source colors.sh.

Здесь только 8 цветов + бит яркости, получается 16 цветов. Для старых терминалов. Я использовал возможность выбирать из 256 цветов, что не все терминалы, быть может, поддерживают.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории