无法在用于zsh提示的函数中更改全局变量

时间:2017-02-22 15:33:41

标签: zsh

我正在尝试构建一个基于时间间隔返回输出的zsh函数。最初“你很渴”的条件是正确的,但是在通过命令行更改变量thirsty并将其设置为false之后,初始的if语句会通过,但其中的变量thirsty没有不要改变global variable thirsty有没有办法修改全局变量thirsty

thirsty=
last_time=

drink_water() {
echo -n "$thirsty"

  if [[ $thirsty == false ]]; then
    last_time="$[$(date +%s) + 10]"
    thirsty=true
    echo -n "${last_time} $(date +%s) ${thirsty}"

  elif [[ $[last_time] -lt $(date +%s) ]]; then
    echo -n " You're thirsty"
  fi

}

1 个答案:

答案 0 :(得分:2)

因为您的代码实际上是从:

调用的
PROMPT='$(drink_water)'

...它包含的所有内容都在作为此命令替换操作的一部分生成的子进程中运行($()是一个“命令替换”:它创建一个新的子进程,运行该子进程中给出的代码,并且读取子进程的输出)。当该子进程退出时,在子进程中对变量(甚至全局变量)的更改将丢失。

如果您将更新代码直接放在precmd函数中,那么它将在每个提示打印之前运行,但不会进行命令替换。那就是:

precmd() {
  local curr_time=$(date +%s) # this is slow, don't repeat it!
  if [[ $thirsty = false ]]; then
    last_time="$(( curr_time + 10 ))"
    thirsty=true
    PROMPT="$last_time $curr_time $thirsty"
  elif (( last_time < curr_time )); then
    PROMPT=" You're thirsty"
  fi
}

当然,您可以使用命令替换来设置PROMPT,但对变量状态的更新必须单独完成,之外<命令替换,如果它们是持续。