Как настроить bash для печати состояния выхода для каждой команды?

12

Каждая команда, запущенная в bash, возвращается с кодом выхода.

Всякий раз, когда я набираю команду в приглашении bash, я хочу, чтобы она показывала состояние выхода, т.е. echo $?

Например, если я запускаю echo "hello";по приглашению bash, вывод должен быть:

linux@linux$ hello
linux@linux$ 0
ravidixit
источник
Как насчет размещения вашего вопроса на unix.stackexchange.com ?
Спасибо @Frank. Но разве это не хорошее место, чтобы поставить этот вопрос?
ravidixit
Я попытался напечатать это как часть переменной PS1, но не работает по причинам, которые я пока не понимаю.
ravidixit

Ответы:

13

Код выхода из последней выполненной команды сохраняется в $?переменной среды. Таким образом, вы можете просто добавить эту переменную в командную строку по умолчанию, и у вас всегда будет напечатан код выхода. Приглашение хранится в $PS1переменной окружения. Первоначально он устанавливается в /etc/bash.bashrcсценарии, а затем в $HOME/.bashrc.

Так что отредактируйте строку $HOME/.bashrc( /etc/bash.bashrcбудет всей системы) из значения по умолчанию:

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

к этому (например):

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w[$?] \$ '

Таким образом, приглашение по умолчанию изменилось на:

user@host:/path/to/dir[0] $

0 в скобках - это ваш код выхода, см.

user@host:~[0] $ ls
user@host:~[0] $ ls /root/
ls: cannot open directory /root/: Permission denied
user@host:~[2] $ ^C
user@host:~[130] $

О значениях см. Http://www.tldp.org/LDP/abs/html/exitcodes.html.

хаос
источник
Я пытался сделать это, но для bash под рукой, он не работает. он всегда показывает [0] для машины, на которой я работаю.
ravidixit
Вы уверены, что запускаете Bash? Можете ли вы скопировать вывод, readlink /proc/$$/exeпожалуйста? 0 означает отсутствие ошибки, вы пытались что-то, что дает ошибку: ^Cили falseили asdasdasd?
хаос
1
@chaos У меня есть PS1 как PS1=$(printf "%s\\\\u@\h:%s%s\w[$?]$%s " "$yellow" "$end" "$blue" "$end"), но он просто показывает 0все время. Есть идеи почему?
Макс
1
Было бы неплохо, если бы статус выхода отображался только, если он
неравен
1
@max Это потому, что ваш $?уже расширен до 0настройки вашего PS1. Делай echo $PS1и увидишь. Вы должны либо использовать одинарные кавычки, либо избегать его как \$?.
Wisbucky
7

Другой способ, который я выбрал из Arch Wiki, заключался в использовании trap:

EC() { echo -e '\e[1;33m'code $?'\e[m\n'; }
trap EC ERR

Эффект:

$ ( exit 1 )
code 1

$ some-non-existent-command
some-non-existent-command: command not found
code 127

$
Мур
источник
2
Это не совсем соответствует требованиям ОП, поскольку он хочет напечатать статус выхода, даже если он равен нулю - но это именно то , что я искал.
Кит Томпсон
2

Вот простой пример:

PS1='$? > '

Если вы используете двойные кавычки, вы должны добавить обратную косую черту, чтобы избежать $:

PS1="\$? > "

Выход:

0 > echo 'ok'
ok
0 > bogus
bogus: command not found
127 > 

Еще лучший способ - печатать код выхода только тогда, когда он не равен нулю.

PS1='${?#0}> '    # single quote example
PS1="\${?#0}> "   # double quote example (requires extra backslash)

Пример вывода:

> echo 'ok'
ok
> bogus
bogus: command not found
127> 

Объяснение: ${var#pattern}это расширение параметра bash, которое означает удаление кратчайшего подходящего шаблона из передней части $ var. Таким образом, в этом случае мы удаляем 0с фронта $?, который будет эффективно урезать код выхода 0.

Если используются двойные кавычки, $?будет подставлено, когда PS1установлено, вместо того, чтобы оцениваться каждый раз. Есть , echo $PS1чтобы подтвердить , что вы не имеете жёстко значение PS1.

wisbucky
источник
Спасибо за январь 2018 года. Мне нужна нормальная подсказка с кодом выхода в начале, если он ненулевой - это очень помогает.
SDsolar