【问题标题】:Set PS1 with subcommand that prints colors使用打印颜色的子命令设置 PS1
【发布时间】:2018-09-13 21:08:44
【问题描述】:

将 ANSI 颜色代码放入 PS1 时,需要用 \[\] 包围它们,否则提示可能会混淆行的可编辑部分从哪里开始。但是,当子命令 ($()) 打印颜色时,\[\] 转义总是按字面意思写入提示符……而且在我的历史记录中,如果命令足够长,提示符就会混淆。

这是一个例子:

ps1test() {
    ps1sub() {
        printf '\[\033[32m\]Hello!\[\033[0m\]'
    }
    PS1='$(ps1sub) \$ '
}

预期:

$ ps1test
Hello! $

实际(由 Git for Windows 安装的bash):

$ ps1test
\[\]Hello!\[\] $

如何让我的 shell 解释子命令中的 \[\] 转义?

【问题讨论】:

  • 与其使用原始颜色代码,不如使用tput 更干净。
  • 更干净的是,但是对tput 的调用过多会显着减慢shell。至少在 Windows 上。但无论如何,问题中的颜色代码只是一个例子。

标签: bash sh prompt git-bash


【解决方案1】:

仅解释文字字符串中的\[s。 \[s 不是由嵌入式扩展产生的。

解决它的最简单方法是让PROMPT_COMMAND 每次都将PS1 设置为一个新的文字值:

updateps1() {
    ps1sub() {
        printf '\[\033[32m\]Hello $RANDOM!\[\033[0m\]'
    }
    PS1="$(ps1sub) \\\$ "
}

PROMPT_COMMAND='updateps1'

【讨论】:

    【解决方案2】:

    如果您尝试创建动态提示,您可能更容易通过调用为PROMPT_COMMAND 的函数设置PS1 值,例如:

    ps1test() {
      ps1sub() {
            printf '\[\033[32m\]Hello!\[\033[0m\]'
        }
        PS1="$(ps1sub)"' \$ ' # notice the double-quote
    }
    PROMPT_COMMAND=ps1test
    

    这对我来说正确呈现为Hello! $

    我使用prompt.gem 来呈现我的提示,你可以看看它是如何configures PROMPT_COMMAND 获得一些灵感的。

    【讨论】:

      【解决方案3】:

      这正是eval 的正确用例:

      ps1test() {  
          ps1sub() {  
              printf '\[\033[31m\]Hello!\[\033[0m\]';     
          };  
          eval PS1="'$(ps1sub) \$ '"; 
      }
      

      【讨论】:

      • 仅当ps1sub 的结果不随上下文变化时。
      • 在这种情况下,它相当于PS1="$(ps1sub) \$ ",但更脆弱
      猜你喜欢
      • 2020-05-16
      • 1970-01-01
      • 2014-04-23
      • 1970-01-01
      • 2017-03-14
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      相关资源
      最近更新 更多