Bash Запрос с последним кодом выхода
Итак, я пытаюсь настроить запрос bash, чтобы он выглядел как
[[email protected] ~]$ _
с цветами. Мне удалось получить постоянные цвета (одинаковые цвета каждый раз, когда я вижу подсказку), но я хочу, чтобы имя пользователя ('feralin') было красным, а не зеленым, если последняя команда имела ненулевой статус выхода. Я придумал:
\e[1;33m[$(if [[ $? == 0 ]]; then echo "\e[0;31m"; else echo "\e[0;32m"; fi)\u\e[[email protected]\e[1;34m\h \e[0;35m\W\e[1;33m]$ \e[m
Однако, по моим наблюдениям, $(if ...; fi)
, кажется, оценивается один раз, когда выполняется .bashrc
, и результат заменяется навсегда после. Это делает имя всегда зеленым, даже если последний код выхода отличен от нуля (как в, echo $?
). Это то, что происходит? Или это просто что-то не так с моей подсказкой? Короче говоря, как мне получить приглашение использовать последний код выхода?
Ответы
Ответ 1
Когда вы начинаете граничить с сложным PS1, вы можете использовать PROMPT_COMMAND
.
С помощью этого вы установите его в функцию, и он будет запущен после каждой команды, чтобы сгенерировать приглашение.
Вы можете попробовать следующее в ~/.bashrc
PROMPT_COMMAND=__prompt_command # Func to gen PS1 after CMDs
__prompt_command() {
local EXIT="$?" # This needs to be first
PS1=""
local RCol='\[\e[0m\]'
local Red='\[\e[0;31m\]'
local Gre='\[\e[0;32m\]'
local BYel='\[\e[1;33m\]'
local BBlu='\[\e[1;34m\]'
local Pur='\[\e[0;35m\]'
if [ $EXIT != 0 ]; then
PS1+="${Red}\u${RCol}" # Add red if exit code non 0
else
PS1+="${Gre}\u${RCol}"
fi
PS1+="${RCol}@${BBlu}\h ${Pur}\W${BYel}$ ${RCol}"
}
Это должно делать то, что вам нравится.
Взгляните на мой bashrc sub file, если вы хотите увидеть все, что я делаю с моей функцией __prompt_command
.
Ответ 2
Если вы не хотите использовать команду приглашения, вам необходимо учесть две вещи:
- получение значения $? перед чем-либо еще, в противном случае это будет превышено
- экранирование всех $в PS1 (поэтому он не оценивается при назначении)
Рабочий пример с использованием переменной
PS1="\$(VALU="\$?" ; echo \$VALU ; date ; if [ \$VALU == 0 ]; then echo zero; else echo nonzero; fi) "
Рабочий пример без переменной
Здесь if должно быть первым, перед любой командой, которая переопределит $?
.
PS1="\$(if [ \$? == 0 ]; then echo zero; else echo nonzero; fi) "
Обратите внимание, как \$()
экранируется, поэтому он не выполняется сразу, но каждый раз, когда используется PS1. Также все использование \$?
Ответ 3
Я хотел сохранить цвета Debian по умолчанию, напечатать точный код и только распечатать его при ошибке:
# Show exit status on failure.
PROMPT_COMMAND=__prompt_command
__prompt_command() {
local curr_exit="$?"
local BRed='\[\e[0;91m\]'
local RCol='\[\e[0m\]'
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\[email protected]\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
if [ "$curr_exit" != 0 ]; then
PS1="[${BRed}$curr_exit${RCol}]$PS1"
fi
}
Ответ 4
многим людям не нужен загадочный шум, такой как $:>
так что это очищенная версия, которая на самом деле работает:
https://0bin.net/paste/Qetj8-OdAyfZrw-l#ZkkIZpF9GQztJfDxCfkOXMY7Q7Tw+xOZuHpxOGG2CcX
Ответ 5
Я разместил решение, но оно было удалено. Я никогда больше не отвечу здесь.
Ответ 6
Улучшено @demure
Я думаю, что это важно, потому что не всегда статус выхода равен 0 или 1.
if [ $EXIT != 0 ]; then
PS1+="${Red}${EXIT}:\u${RCol}" # Add red if exit code != 0
else
PS1+="${Gre}${EXIT}:\u${RCol}" # Also displays exit status
fi