BASH 支持$PROMPT_COMMAND
环境变量,该变量定义在任何第一级交互提示之前要执行的命令。我正在寻找与之等效的 ZSH。
文档说precmd
我可以定义一个函数来实现这一点;但是,我不知道如何从环境变量中定义它。
我考虑过传递一个环境变量,让 ZSH 读取包含该函数定义的文件,但是 ZSH似乎不支持这样的事情:它只读取全局文件,然后读取每个用户的文件。我可以替换它们,但如果不修改文件,我就无法添加文件,而修改文件是我做不到的。
那么,如何通过环境变量在 ZSH 中定义预提示钩子,就像在 BASH 中一样$PROMPT_COMMAND
?
答案1
$PROMPT_COMMAND
我想到的最简单的模拟 bash 的方法是使用precmd
钩子,正如你已经知道的那样。将其定义为
precmd() { eval "$PROMPT_COMMAND" }
你可以做类似的事情:
$ PROMPT_COMMAND='echo Hello, it is now $(date)'
Hello, it is now Mon, Mar 31, 2014 7:08:00 PM
$ whoami
user
Hello, it is now Mon, Mar 31, 2014 7:08:21 PM
$
请注意该示例中的单引号,否则$(date)
会过早扩展,即在定义时就已经扩展$PROMPT_COMMAND
,而不是在提示之前调用时。
如果您想保留(并且不想改变)现有定义,您可以使用该方法:
$ prmptcmd() { eval "$PROMPT_COMMAND" }
$ precmd_functions=(prmptcmd)
这样,该prmptcmd
函数将在现有precmd()
函数之后执行。
最后,这里有一种适合在程序包中使用的方式,既不需要修改用户或系统文件,也不能交互输入命令。
生成 bash 会话的一个例子可能是
PROMPT_COMMAND="echo foo" bash
要生成 zsh,你可以使用
ZDOTDIR=/program/dir zsh
这会导致/program/dir/.zshrc
被调用。在此文件中,precmd()
可以按上述说明定义钩子。如果您想要用户的设置此外source $HOME/.zshrc
程序的 .zshrc 中也包含这些文件。此设置易于维护,因为程序目录之外的文件不会被修改。
最后补充一点,这里有一个概念证明,说明如何让新用户也受到欢迎。在您的/program/dir/.zshenv
rc 配置文件中使用以下代码:
echo define precmd, traps, etc.
autoload -Uz zsh-newuser-install
if [[ ! -e "$HOME/.zshrc" ]]; then
zsh-newuser-install -f
mv $ZDOTDIR/.zshrc $HOME/.zshrc
else
builtin source $HOME/.zshrc
fi
答案2
正如 @mypy 所述,Zsh 的precmd
工作方式与 Bash 类似PROMPT_COMMAND
。
这是一个适用于 Bash 或 Zsh 且不使用的示例eval
:
## ~/myprompt.sh
# 'ZSH_VERSION' only defined in Zsh
# 'precmd' is a special function name known to Zsh
[ ${ZSH_VERSION} ] && precmd() { myprompt; }
# 'BASH_VERSION' only defined in Bash
# 'PROMPT_COMMAND' is a special environment variable name known to Bash
[ ${BASH_VERSION} ] && PROMPT_COMMAND=myprompt
# function called every time shell is about to draw prompt
myprompt() {
if [ ${ZSH_VERSION} ]; then
# Zsh prompt expansion syntax
PS1='%{%F{red}%}%n%{%f%}@%{%F{red}%}%m %{%F{cyan}%}%~ %{%F{white}%}%# %{%f%}'
elif [ ${BASH_VERSION} ]; then
# Bash prompt expansion syntax
PS1='\[\e[31m\]\u\[\e[0m\]@\[\e[31m\]\h \[\e[36m\]\w \[\e[37m\]\$ \[\e[0m\]'
fi
}
从 shell 初始化脚本运行:
## ~/.bashrc
. ~/myprompt.sh
和:
## ~/.zshrc
. ~/myprompt.sh
这里的提示只是示例。当然,你可以做更棘手的事情。
提示功能的设置请参见:http://zsh.sourceforge.net/Doc/Release/Functions.html#index-precmd和http://www.gnu.org/software/bash/manual/bashref.html#Printing-a-Prompt。
有关提示扩展的详细信息,请参阅http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html和http://www.gnu.org/software/bash/manual/bashref.html#Printing-a-Prompt。