zsh:自动为目录设置环境变量

And*_*rew 6 zsh environment-variables

假设我有一个项目:

~/working_dir
Run Code Online (Sandbox Code Playgroud)

每当我从此目录运行命令时,我都需要设置某些环境变量。所以我可以像这样导出它们:

export VAR=value
Run Code Online (Sandbox Code Playgroud)

然而,有很多这样的东西而且它变得乏味,而且我有时会忘记并运行一个命令只会让它失败,因为它缺少为其提供 API 密钥或其他东西的环境变量。

有没有办法让 zsh 记住这个目录的这些环境变量,以便我从该目录运行任何命令时,它会在设置了这些环境变量的情况下运行?

Sim*_*mba 12

与为此而设计的其他工具相比,direnv是其中最好的。

direnv是 shell 的环境切换器。它知道如何挂钩 bash、zsh、tcsh、fish shell 和 elvish 以根据当前目录加载或卸载环境变量。这允许特定于项目的环境变量而不会使文件混乱~/.profile

direnv与其他类似工具的区别是什么:

  • direnv用 Go 编写,比用 Python 编写的版本更快
  • direnv支持从特定目录退出时卸载环境变量
  • direnv覆盖许多贝壳

类似项目

  • 环境模块- 最古老(以一种好的方式)的环境加载系统之一
  • autoenv——轻量级;不支持卸载;用Python写的很慢
  • zsh-autoenv - autoenv 和smartcd的功能丰富的混合:进入/离开事件、嵌套、存储(仅限 Zsh)。
  • asdf - 具有插件系统的纯 bash 解决方案


sim*_*ont 8

可以这样做 - 这是一个截屏视频,使用Grml ZSH配置

更多信息:

编辑:这实际上很容易做到。这是您的相关部分~/.zshrc

function chpwd_profiles() {
    local profile context
    local -i reexecute

    context=":chpwd:profiles:$PWD"
    zstyle -s "$context" profile profile || profile='default'
    zstyle -T "$context" re-execute && reexecute=1 || reexecute=0

    if (( ${+parameters[CHPWD_PROFILE]} == 0 )); then
        typeset -g CHPWD_PROFILE
        local CHPWD_PROFILES_INIT=1
        (( ${+functions[chpwd_profiles_init]} )) && chpwd_profiles_init
    elif [[ $profile != $CHPWD_PROFILE ]]; then
        (( ${+functions[chpwd_leave_profile_$CHPWD_PROFILE]} )) \
            && chpwd_leave_profile_${CHPWD_PROFILE}
    fi  
    if (( reexecute )) || [[ $profile != $CHPWD_PROFILE ]]; then
        (( ${+functions[chpwd_profile_$profile]} )) && chpwd_profile_${profile}
    fi  

    CHPWD_PROFILE="${profile}"
    return 0
}
# Add the chpwd_profiles() function to the list called by chpwd()!
chpwd_functions=( ${chpwd_functions} chpwd_profiles )
Run Code Online (Sandbox Code Playgroud)

激活您想要的每个目录的配置文件:

zstyle ':chpwd:profiles:/path/to/directory(|/|/*)' profile NAME
Run Code Online (Sandbox Code Playgroud)

并且不要忘记实际制作个人资料:

chpwd_profile_NAME() {
    [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1
    print "chpwd(): Switching to profile: $profile"

    export VAR=value
}
Run Code Online (Sandbox Code Playgroud)

编辑 #2:与命名目录[Stackoverflow.net]结合使用实际上会相当整洁。

  • 这个解决方案没有什么“容易”的。 (6认同)

小智 5

尽管这是一个老问题,但我想从https://coderwall.com/p/a3xreg/per-directory-zsh-config添加这个简单的解决方案

// Add this to your ~/.zshrc
function chpwd() {
  if [ -r $PWD/.zsh_config ]; then
    source $PWD/.zsh_config
  else
    source $HOME/.zshrc
  fi
}
Run Code Online (Sandbox Code Playgroud)

  • 这很好用,但如果在 zsh 初始化时已经加载了 `.zshrc`,您可能可以跳过第 5-6 行。 (2认同)

小智 0

不是每个目录,不,但如果它们相同,您可以将它们放入启动文件中(bash 的 .bash_profile,不确定 zsh 的是什么)。否则,我建议将所有设置放入该目录中的文件中,并在运行命令之前获取它。这不是一个理想的解决方案,但我认为它接近您能找到的最好的解决方案。