【问题标题】:Linux shell (Bash/Z shell) - change background color when under a specific directoryLinux shell (Bash/Z shell) - 在特定目录下更改背景颜色
【发布时间】:2016-07-11 13:45:32
【问题描述】:

每次进入特定目录时,我都想更改 shell(Z shell,但 Bash 也可以)的背景颜色。例如,我想每次在 /mnt/data 中时将背景颜色更改为红色,如果我退出 /mnt/data/...

要更改背景并保留当前提示,我会这样做:

export PS1="$PS1 %{$'\e[0;41m'%}"

我不确定如何将其连接起来,以便在每次更改工作目录时对其进行评估(包装在 if 语句中)。

【问题讨论】:

  • 所以提示后要切换到后台?

标签: linux bash shell console zsh


【解决方案1】:

诀窍是在 PS1 中使用命令替换。以下类型在 Bash 中对我有用:

PS1='$(if [[ $PWD == /mnt/data* ]] ; then printf "\[\e[0;41m\]" ; else printf "\[\e[m\]" ; fi) %'

我所说的“种类”是指在切换到/从目录后立即在命令行上的行为有点奇怪(例如,在您按下 Backspace 后背景会发生变化)。

您也可以使用PROMPT_COMMAND shell 变量,它比提示本身更适合代码:

PROMPT_COMMAND='if [[ $PWD == /mnt/data* ]] ; then printf "\e[0;41m" ; else printf "\e[m" ; fi'

将代码保留在具有所有适当缩进的函数中更简洁,只需从变量中调用函数:

colour_mnt_data () {
    if [[ $PWD == /mnt/data* ]] ; then
        printf '\e[0;41m'
    else
        printf '\e[m'
    fi
}
PROMPT_COMMAND='colour_mnt_data'

【讨论】:

  • 您也可以将缩进保留在 PROMPT_COMMAND 赋值的 RHS 中。换行和缩进在单引号内无效。
  • @WilliamPursell:是的。但是对于一个函数,编辑器中的语法高亮是有效的,你可以在提示符之外测试函数,等等。
【解决方案2】:

zsh的答案(虽然第二部分可以改成bash):

这是一个由两部分组成的问题:

  1. 对目录更改采取行动: 对于zsh,您只需使用chpwd 挂钩函数即可。每次更改当前工作目录时,都会调用 chpwd 以及 chpwd_functions 数组中列出的任何函数。

    所以,如果你想对某些目录做出反应,你可以使用类似这样的东西

    # load helper function to manipulate hook arrays
    autoload -Uz add-zsh-hook
    
    # define hook function, decide on action based on $PWD, the new pwd.
    chback_on_chdir () {
        case $PWD in
            /mnt/data/* )
                # change background, when entering subdirectories of "/mnt/data"
                ;;
            /home )
                # change background, when entering exactly "/home"
                ;;
            /usr | /usr/* ) 
                # change background, when entering "/usr" or a subdirectory thereof
                ;;
            * )
                # change background, when entering any other directory
                ;;
        esac
    }
    
    # add chback_on_chdir to chpwd_functions
    add-zsh-hook chpwd chback_on_chdir
    
  2. 更改背景颜色:实际上有两种方法可以更改背景颜色。

    • 您可以在终端中可用的颜色范围内更改以下打印字符的背景(即您在示例中所做的)。在zsh 中可以这样完成(chdir 钩子的缩短示例):

      # allow for parameter substitution in prompts
      setopt PROMPT_SUBST
      # add string `$COLOR` to $PS1. 
      # Note the `\` before `${COLOR}`, which prevents immediate evaluation.
      # `${COLOR}` will be substituted each time the prompt is printed
      PS1="$PS1\${COLOR}"
      
      chpwd () {
          case $PWD in
              /mnt/data/* )
                  # set background color to red
                  COLOR='%K{red}'
                  ;;
              * )
                  # reset background color to default
                  COLOR='%k'
                  # could also be just an empty string
                  #COLOR=''
                  # or unset
                  #unset COLOR
                  ;;
          esac
      }
      
    • 在一些(很多?)终端中,您还可以重新定义默认背景颜色。这实际上会改变所有地方的背景颜色,即使在已经打印的文本和“未打印”的位置上也是如此。这可以通过使用XTerm Control Sequences 来完成,尽管它们的名字也可以在其他终端仿真器中使用。 (我用xtermurxvtgnome-terminaltermite 测试成功)。有问题的控制序列是

      ESC]11;<color>ST
      

      其中ESC 是转义字符\e&lt;color&gt; 是颜色规范(例如red#ff0000rgb:ff/00/00rgbi:1/0/0 - 实际工作可能取决于终端)和ST字符串终止符 \e\\ (ESC\)。您可以将其发送到终端

      printf "\e]11;red\e\\"
      

      您可以使用控制序列将颜色重置为配置的默认值

      ESC]111ST
      

      使用命令

      printf "\e]111\e\\"
      

      所以,如果你平时的背景是黑色的,想在输入/mnt/data或者它下面的目录时把它染成微红色,你可以使用:

      chpwd () {
          case $PWD in
              /mnt/data | /mnt/data/* )
                  # set background color to a dark red
                  printf "\e]11;#1f0000\e\\"
                  ;;
              * )
                  # reset the background color to configured default
                  printf "\e]111\e\\"
                  ;;
          esac
      }
      

      注意:如果启用了透明度,我发现它似乎不适用于urxvt

      可以通过将颜色规范替换为?来检索当前值:

      printf "\e]11;?\e\\" ; sleep 1
      

      需要sleep 1,以免提示立即覆盖输出。

【讨论】:

    【解决方案3】:

    您将需要编写一个脚本文件,其中包含您可以调用的函数来确定您的 PS1 应该是什么,因为您所在的目录。

    然后,您在 .bashrc 中获取此脚本文件并设置您的 PS1,以便它从您的脚本文件中调用该函数来设置其值。

      . ~/.myCleverPS1
    
      export PS1='$PS1 $(myCleverPS1func " (%s)") $ '
    

    您可以查看的一个示例是 git-completion 脚本,只要您在 git repo 目录中,它就会将当前分支的名称添加到提示符中(并且也可以选择着色)。

    参见示例:https://github.com/git/git/tree/master/contrib/completion

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-17
      • 1970-01-01
      • 1970-01-01
      • 2019-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多