Linux shell (Bash/Z shell) - 在特定目录下更改背景颜色
Linux shell (Bash/Z shell) - change background color when under a specific directory
我想在每次进入特定目录时更改 shell 的背景颜色(Z shell,但 Bash 也可以)。比如我想每次在/mnt/data的时候把背景颜色改成红色,如果出了/mnt/data就改回正常/...
要更改背景并保留我当前的提示,我这样做:
export PS1="$PS1 %{$'\e[0;41m'%}"
我不确定如何连接它以便在每次更改工作目录时对其进行评估(包装在 if 语句中)。
诀窍是使用 PS1 中的命令替换。 Bash 中的以下类型对我有用:
PS1='$(if [[ $PWD == /mnt/data* ]] ; then printf "\[\e[0;41m\]" ; else printf "\[\e[m\]" ; fi) %'
我所说的“有点”是指在更改 to/from 目录后立即在命令行上的行为有点奇怪(例如,在您按下 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'
您需要编写一个脚本文件,其中包含您可以调用的函数以确定您的 PS1 应该是什么,因为您所在的目录。
然后,您在 .bashrc 中获取此脚本文件并设置 PS1 以便它调用脚本文件中的函数来设置其值。
. ~/.myCleverPS1
export PS1='$PS1 $(myCleverPS1func " (%s)") $ '
您可以查看的一个示例是 git-completion 脚本,它会在您位于 git 存储库目录时将当前分支的名称添加到提示中(并且也可以选择着色).
参见示例:https://github.com/git/git/tree/master/contrib/completion
zsh
的答案(虽然第二部分可以改编为bash
):
这是一个两部分的问题:
对目录更改进行操作: 对于 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
更改背景颜色: 其实有两种方法可以更改背景颜色。
您可以在终端可用的颜色范围内更改以下打印字符的背景(即您在示例中所做的)。在 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
}
在某些(很多?)终端中,您还可以重新定义默认背景颜色。这实际上会改变所有地方的背景颜色,甚至在已经打印的文本和 "unprinted" 位置。这可以通过利用 XTerm Control Sequences 来完成,尽管它们的名称不同,它也可以在其他终端仿真器中工作。 (我用 xterm
、urxvt
、gnome-terminal
和 termite
测试成功)。有问题的控制顺序是
ESC]11;<color>ST
其中 ESC
是转义字符 \e
,<color>
是颜色规范(例如 red
、#ff0000
、rgb:ff/00/00
、 rgbi: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
以便输出不会立即被提示覆盖。
我想在每次进入特定目录时更改 shell 的背景颜色(Z shell,但 Bash 也可以)。比如我想每次在/mnt/data的时候把背景颜色改成红色,如果出了/mnt/data就改回正常/...
要更改背景并保留我当前的提示,我这样做:
export PS1="$PS1 %{$'\e[0;41m'%}"
我不确定如何连接它以便在每次更改工作目录时对其进行评估(包装在 if 语句中)。
诀窍是使用 PS1 中的命令替换。 Bash 中的以下类型对我有用:
PS1='$(if [[ $PWD == /mnt/data* ]] ; then printf "\[\e[0;41m\]" ; else printf "\[\e[m\]" ; fi) %'
我所说的“有点”是指在更改 to/from 目录后立即在命令行上的行为有点奇怪(例如,在您按下 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'
您需要编写一个脚本文件,其中包含您可以调用的函数以确定您的 PS1 应该是什么,因为您所在的目录。
然后,您在 .bashrc 中获取此脚本文件并设置 PS1 以便它调用脚本文件中的函数来设置其值。
. ~/.myCleverPS1
export PS1='$PS1 $(myCleverPS1func " (%s)") $ '
您可以查看的一个示例是 git-completion 脚本,它会在您位于 git 存储库目录时将当前分支的名称添加到提示中(并且也可以选择着色).
参见示例:https://github.com/git/git/tree/master/contrib/completion
zsh
的答案(虽然第二部分可以改编为bash
):
这是一个两部分的问题:
对目录更改进行操作: 对于
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
更改背景颜色: 其实有两种方法可以更改背景颜色。
您可以在终端可用的颜色范围内更改以下打印字符的背景(即您在示例中所做的)。在
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 }
在某些(很多?)终端中,您还可以重新定义默认背景颜色。这实际上会改变所有地方的背景颜色,甚至在已经打印的文本和 "unprinted" 位置。这可以通过利用 XTerm Control Sequences 来完成,尽管它们的名称不同,它也可以在其他终端仿真器中工作。 (我用
xterm
、urxvt
、gnome-terminal
和termite
测试成功)。有问题的控制顺序是ESC]11;<color>ST
其中
将其发送到终端ESC
是转义字符\e
,<color>
是颜色规范(例如red
、#ff0000
、rgb:ff/00/00
、rgbi: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
以便输出不会立即被提示覆盖。