什么是 BASH 的 $PROMPT_COMMAND 的 ZSH 等价物?

Shn*_*sel 39 bash zsh shell environment-variables

BASH 支持$PROMPT_COMMAND定义在任何第一级交互式提示之前要执行的命令的环境变量。我正在寻找等效的 ZSH。

文档precmd我可以定义一个函数来实现它;但是,我不知道如何从环境变量中定义它。

我考虑过传递一个环境变量,让 ZSH 读取包含该函数定义的文件,但 ZSH似乎不支持这样的事情:它只读取全局文件,然后读取每个用户的文件。我可以替换它们,但我不能在不修改文件的情况下添加它们,这是我做不到的。

那么如何通过环境变量在 ZSH 中定义预提示钩子,就像我$PROMPT_COMMAND在 BASH 中所做的那样?

mpy*_*mpy 34

$PROMPT_COMMAND我想到的模拟 bash 的最简单方法是使用precmd钩子,正如您已经想到的那样。将其定义为

precmd() { eval "$PROMPT_COMMAND" }
Run Code Online (Sandbox Code Playgroud)

你可以做这样的事情:

$ 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     
$
Run Code Online (Sandbox Code Playgroud)

请注意该示例中的单引号,否则$(date)会过早扩展,即在定义$PROMPT_COMMAND时已经扩展而不是在提示之前调用时。


如果您想保留(并且不想更改)现有定义,您可以使用该方法:

$ prmptcmd() { eval "$PROMPT_COMMAND" }
$ precmd_functions=(prmptcmd)
Run Code Online (Sandbox Code Playgroud)

这样,prmptcmd功能在现有precmd()功能之后执行。


最后,这里有一种适合在程序包中使用的方式,它既不能修改用户文件或系统文件,也不能交互式输入命令。

生成 bash 会话的示例可能是

PROMPT_COMMAND="echo foo" bash
Run Code Online (Sandbox Code Playgroud)

要生成 zsh,您可以使用

ZDOTDIR=/program/dir zsh
Run Code Online (Sandbox Code Playgroud)

这导致/program/dir/.zshrc来源。在这个文件中,precmd()钩子可以按照上面的解释定义。如果您希望用户的设置另外包含source $HOME/.zshrc程序的 .zshrc 中的等等。此设置是可维护的,因为不会修改程序目录之外的文件。


作为最后一个补充,这里是一个如何保持新用户受欢迎的概念证明。在/program/dir/.zshenvrc 配置文件中使用以下代码:

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
Run Code Online (Sandbox Code Playgroud)

  • 好的,这说明了很多——bash 的一个最小例子就是`PROMPT_COMMAND="echo foo" bash`,对吧?这是生成 zsh 的可能性吗:`ZDOTDIR=/program/dir zsh`。然后`/program/dir/.zshrc` 是在启动时获取的,您可以在其中定义 precmd() 钩子。如果您希望用户在程序的 zshrc 中另外包含 `source $HOME/.zshrc` 等。这应该很容易维护,因为没有修改程序目录之外的文件。 (2认同)

jwf*_*arn 9

正如@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
}
Run Code Online (Sandbox Code Playgroud)

从 shell 初始化脚本运行:

## ~/.bashrc
. ~/myprompt.sh
Run Code Online (Sandbox Code Playgroud)

和:

## ~/.zshrc
. ~/myprompt.sh
Run Code Online (Sandbox Code Playgroud)

这里的提示只是示例。一个人绝对可以做更多棘手的事情。

设置提示功能详见:http : //zsh.sourceforge.net/Doc/Release/Functions.html#index-precmdhttp://www.gnu.org/software/bash/manual/bashref.html #Printing-a-Prompt

有关提示扩展的详细信息,请参阅http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.htmlhttp://www.gnu.org/software/bash/manual/bashref.html#Printing-a -提示