Ответ 1
Немного о злоупотреблении printf
:
printf '%.*s' $? $?
Иногда я запускаю команду с большим количеством выходных данных. Иногда последние 30-40 строк этого выхода (a.k.a. - единственная часть вывода, которую я когда-либо видел) прекрасно, но намного дальше, произошла ошибка. Я хотел бы, чтобы было легче заметить, что команда не удалась. Для этого я хочу, чтобы код возврата был частью моего приглашения. Итак, я взял свой PS1:
[\D{%Y-%m-%d} \t] \[\e]0;\[email protected]\h: \w\a\]\$
... и расширил его до:
[\D{%Y-%m-%d} \t] ${?/^0$/} \[\e]0;\[email protected]\h: \w\a\]\$
Это приведет к следующему приглашению:
[2011-05-10 09:38:07] 0 [email protected]:~$
Тем не менее, я хотел бы найти способ, чтобы он включал только код выхода, если он был не 0. Как я могу это сделать? Конечно, я мог бы использовать
$(echo \$? | sed -e blah)
но как легкий, как sed, он все еще довольно тяжелый вес, чем bash встроенный материал.
Немного о злоупотреблении printf
:
printf '%.*s' $? $?
Для меня работает следующее:
PS1="[\D{%Y-%m-%d} \t] \[email protected]\h:\w\a \${?##0} \$ "
[2011-07-25 11:56:57] [email protected]:~ $<br>
there is an extra space there ---------^^ not sure if that a problem for you
[2011-07-25 11:57:39] [email protected]:~ 130 $
Вы можете использовать bash встроенное сопоставление шаблонов:
$ rc=0
$ echo ${rc##0}
$ rc=123
$ echo ${rc##0}
123
Вот что я использую в .bashrc, чтобы получить красное число с кодом выхода. Подробный, но он выполняет свою работу и должен быть переносимым.
highlight()
{
if [ -x /usr/bin/tput ]
then
tput bold
tput setaf $1
fi
shift
printf -- "[email protected]"
if [ -x /usr/bin/tput ]
then
tput sgr0
fi
}
highlight_error()
{
highlight 1 "[email protected]"
}
highlight_exit_code()
{
exit_code=$?
if [ $exit_code -ne 0 ]
then
highlight_error "$exit_code "
fi
}
PS1='$(highlight_exit_code)...'
Вы можете поместить в свой PS1-оператор if, который выдает статус выхода, только если он не равен нулю:
PS1='[\D{%Y-%m-%d} \t] $(es=$?; if [ $es -ne 0 ]; then echo $es; fi) \[\e]0;\[email protected]\h: \w\a\]\$'
Общим способом сделать это является использование trap ... ERR
для выполнения произвольного кода при сбое команды:
$ trap 'echo $?' ERR
$ true
$ false
1
$
Классическая шутка UNIX - trap 'echo You have new mail.' ERR
Для пользователей zsh: вставьте это в свой PROMPT: %(?,, -%?-)
Это подсказка, которую я использую, вставляю в .bashrc и источник, чтобы использовать ее. Как вы видите, PREV_RET_VAL добавляется к PS1 только в том случае, если значение не равно 0.
COLOR_RED_BOLD="\[\e[31;1m\]"
COLOR_GREEN_BOLD="\[\e[32;1m\]"
COLOR_NONE="\[\e[0m\]"
# prompt function
promptFunc()
{
PREV_RET_VAL=$?;
PS1=""
PS1="${PS1}\e[1;30m[\e[1;34m\[email protected]\H\e[1;30m:\e[0;37m \e[0;32m\d \T\e[1;30m]\e[1;37m \w\e[0;37m\[\033]0; \w - \[email protected]\H \007\]\n\[\] "
if test $PREV_RET_VAL -eq 0
then
PS1="${PS1}${COLOR_GREEN_BOLD}\\$ ${COLOR_NONE}"
else
PS1="${PS1}${COLOR_RED_BOLD}\\$ [${PREV_RET_VAL}] ${COLOR_NONE}"
fi
}
PROMPT_COMMAND=promptFunc
Пример одиночной кавычки:
PS1='${?#0}> '
Пример двойной кавычки (обратите внимание на дополнительную обратную косую черту, чтобы избежать $
)
PS1="\${?#0}> "
Пример вывода:
> echo 'ok'
ok
> bogus
bogus: command not found
127>
Объяснение: ${var#pattern}
- это расширение параметра bash, которое означает удаление кратчайшего совпадающего шаблона с лицевой стороны $var. Таким образом, в этом случае мы удаляем 0
с фронта $?
, что эффективно сокращает код выхода 0
.
Если использовать двойные кавычки, $?
будет заменен, когда PS1
будет установлен, а не будет оцениваться каждый раз. Сделайте echo $PS1
, чтобы подтвердить, что у вас нет жестко заданного значения в PS1
.