如何在不中断行长计算的情况下将命令包含在Bash的PS1中?


13

Tonin 在我的默认提示中指出了一个错误。最小示例:

  1. 设置PS1:

    PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " ")$ '

    此时,提示如下所示:

    $ 
  2. 现在通过运行触发退出代码输出:

    false

    现在,提示在行首包含红色的退出代码:

    1 $ 
  3. Ctrl- r
  4. 输入“ false”。现在,提示仅包含搜索:

    (reverse-i-search)`false': false
  5. Enter

现在,最终的终端历史记录包含以下内容:

1 $ch)`false': false

预期产量:

1 $ false

也就是说,历史记录搜索输出似乎与提示混合在一起,并且隐藏了实际运行的命令。

我尝试通过使用PROMPT_COMMAND解决此问题:

set_exit_code() {
    exit_code=$?
    [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " "
}
set_bash_prompt() {
    PS1='$(set_exit_code)$ ' # Double quotes give the same result
}
PROMPT_COMMAND=set_bash_prompt

这似乎不起作用-搜索和运行后,该行看起来与之前完全相同。

我怎样才能解决这个问题?


Answers:


8

我在askubuntu.com上找到了答案。@qeirha提到您必须告诉bash不应在提示的长度中计算字符序列,您可以通过将其括起来来实现\[ \]。根据提供的示例,这是一种解决方案:

red=$(tput setaf 1)

reset=$(tput sgr0)

[ "$PS1" = "\\s-\\v\\\$ " ] && PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$red\] $exit_code \[$reset\] " ")$ '

无需去询问Ubuntu。我们在这里也已经对这个问题有了足够的答案。
manatwork 2013年

谢谢@manatwork的建议!我想对解释给予适当的感谢,并出于礼貌提供了参考。
蒂莫西·马丁

信用不成问题。但是,在谈论问题时:原始的反斜杠通常会从Markdown中消失,所以您的普通\ [在您的帖子中成为了[,因此显示的代码无法通过将其复制粘贴到终端中而起作用。可以通过使用内联代码或代码块标记来避免这种情况。(如何使用Markdown或HTML设置帖子格式?
manatwork 2013年

1
天哪!我已经解决了其他PS1代码的相同问题,为什么我没有看到那个?
l0b0

1
PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] " ")$ '

(对不起,这里没有解释。请参阅如何正确自定义PS1?或有关提示长度计算问题和\[..的任何其他问题\]。)


对于第二个@ l0b0问题,我将使用PS1进行补充,\[...\]只要您可以将要生成提示的所有代码放在单个字符串中,它就可以正常工作。但是,如果要将代码拆分为小函数,则会遇到无法将起始括号和结尾括号放在同一字符串/函数中的情况。这打破了换行。除非PROMPT_COMMANDPS1在每次提示时都使用来重新计算。
Tonin

1

扩展@manatwork答案,但保持代码将PS1计算拆分为不同的功能,可以按以下方式编写提示:

set_exit_code() {
    exit_code=$?
    [[ $exit_code -eq 0 ]] || printf "\[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] "
}
set_bash_prompt() {
    PS1="$(set_exit_code)$ " # with double quotes!
}
PROMPT_COMMAND=set_bash_prompt

设置PS1printf在函数中使用时,双引号都是必需的。


为了将来参考,请在您的.bashrc文件中使用bash函数-不要将代码放在单独的文件中并进行调用。
starbeamrainbowlabs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.