【问题标题】:Correct return value in BASH promptBASH 提示符中的正确返回值
【发布时间】:2020-04-14 09:45:13
【问题描述】:

这是在 Ubuntu 19.10 机器上设置提示的 .bashrc 文件的一部分:

# Terminal tab name in gnome-terminal or Guake
PROMPT_COMMAND='echo -ne "\033]0;$(basename ${PWD})\007"'

GIT_PS1_SHOWCOLORHINTS=yes
RET=\$?
source /usr/lib/git-core/git-sh-prompt

if [ "$color_prompt" = yes ]; then
    color_reset=$(tput sgr0)
    color_bold=$(tput bold)
    color_white=$(tput setaf 7)
    color_jobs=$(tput setaf 7)
    color_user=$(tput setaf 3)
    color_dir=$(tput setaf 4)
    color_load=$(tput setaf 5)
    color_succeed=$(tput setaf 2)
    color_fail=$(tput setaf 1)
    sep=$(tput setaf 7)\)
    PS1="${color_user}\u${sep}\[\D{%T}\]${sep}${color_reset}\$(__git_ps1)${color_dir}\W${color_reset}${sep}\`if [[ ${RET} == 0 ]]; then echo \"${color_succeed}0\"; else echo \"${color_fail}${RET}\"; fi\`${color_white}${sep}${color_reset}\$ "
else
    PS1="\u${sep}\[\D{%T}\]${sep}\$(__git_ps1)\W${sep}\`if [[ ${RET} == 0 ]]; then echo \"0\"; else echo \"${RET}\"; fi\`${sep}\$ "
fi

这是一个正在使用的命令行示例:

snim2)10:39:53)dirname)0)$ cd scratch
snim2)10:39:54)scratch)0)$ git init
Initialised empty Git repository in .../scratch/.git/
snim2)10:39:56) (master)scratch)0)$ asdasda
asdasda: command not found
snim2)10:40:05) (master)scratch)1)$ $?
127: command not found
snim2)10:40:10) (master)scratch)1)$ 

如您所见,当命令的返回码非零时,它在提示符中显示为1),而不是显示正确的返回码——在本例中为127)。如何解决这个问题?

【问题讨论】:

  • 不应该 RET=\$? 只是 RET=$? 吗?无需转义$ 即可获得latest exit code
  • 好点。将该行更改为 RET='$?' 并没有给出不同的结果,并且没有这些单引号,提示总是显示最后一个命令成功。
  • 单引号不会扩展变量,因此RET 将字面意思是'$?'RET=$? 应该没问题! (不带引号)
  • $(__git_ps1) 是最后一个命令。请不要使用反引号`。请改用$(...)。奇怪的大括号用法 - 只需将其写在单引号中。 PS1="\u${sep} - sep 在此处未设置。我想知道\) 中的sep=...\) 是不是一个错字。
  • sep 设置在PS1... 上方的行上,对吗?我已经做出了你们俩建议的更改,但这并不能解决问题。 RET=$? 仍然显示每个成功的命令...

标签: bash prompt ps1


【解决方案1】:

你这样做:

..$(__git_ps1)...\`if [[ $? == 0 ]];

$? 将是__git_ps1 的返回状态,而不是命令行上最后执行的命令。

尝试立即将退出返回值保存在第一个命令替换块中:

if [ "$color_prompt" = yes ]; then
    color_reset=$(tput sgr0)
    color_bold=$(tput bold)
    color_white=$(tput setaf 7)
    color_jobs=$(tput setaf 7)
    color_user=$(tput setaf 3)
    color_dir=$(tput setaf 4)
    color_load=$(tput setaf 5)
    color_succeed=$(tput setaf 2)
    color_fail=$(tput setaf 1)
    sep=$(tput setaf 7)\)
else
    color_reset=
    color_bold=
    color_white=
    color_jobs=
    color_user=
    color_dir=
    color_load=
    color_succeed=
    color_fail=
    sep=\)  # remove the braces...
fi

# note the quotes - "" expand at setting time, '' expand at runtime
PS1=
PS1+="${color_user}\u${sep}\[\D{%T}\]${sep}${color_reset}"
PS1+='$('
   PS1+='ret=$?; '  # first thing we do - save the exit return value
   PS1+='__git_ps1; '
   PS1+='printf "%s" "'
      PS1+="${color_dir}\W${color_reset}${sep}"
      PS1+='"; '
   PS1+='if ((ret == 0)); then '
       PS1+='printf "%s" "'
          PS1+="${color_succeed}"  # expand variable on assignment side
          PS1+='0"; '  # this looks strange. Just print first the color, then $ret...
   PS1+='else '
      PS1+='printf "%s" "'
           PS1+="$color_fail"
           PS1+='$ret"; '
   PS1+='fi '
PS1+=')'
PS1+="${color_white}${sep}${color_reset}"
PS1+='\$ '  # note - this is *not* "\$ "

【讨论】:

  • 这很有意义,而且您对代码的分解比我做得更好!非常感谢!
  • 另外:您应该将所有不可打印的字符括在 \[ \] 中。否则 Home End 键将无法正确检测行的结束/开始。 \[${color_white}\] 等所有颜色也是如此(可能在分配时)。并将\[\D{%T}\] 更改为[\D{%T}]。见gnu.org/software/bash/manual/html_node/…
【解决方案2】:

我看不到您在哪里更新了RET 的值。动态部分使用PROMPT_COMMAND

$ PS1='[\$?=$RET]$ '; PROMPT_COMMAND='RET=$?; if [ "$RET" -eq 0 ]; then RET="good $RET"; else RET="bad $RET"; fi'
[$?=good 0]$ echo okay
okay
[$?=good 0]$ lkjjlk
-bash: lkjjlk: command not found
[$?=bad 127]$ echo $?
127
[$?=good 0]$ ls lkjjl
ls: cannot access 'lkjjl': No such file or directory
[$?=bad 2]$ ls lkjjl; echo $?
ls: cannot access 'lkjjl': No such file or directory
2
[$?=good 0]$

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 2017-04-28
    • 2011-01-08
    • 2018-05-06
    相关资源
    最近更新 更多