关于使环境依赖于当前目录

关于使环境依赖于当前目录

我认为如果当前目录决定了一个人的 shell 环境,这将是有用/方便的。这意味着该命令

cd /my/projects/foo

...例如,不仅会设置当前工作目录(并更新、、、$PWD等),而且还会在一个文件中调整许多其他环境元素(shell 选项、变量、函数、别名等)。方式与新的内容相适应。$OLDPWD$dirstackPWD

乍一看,这似乎是一个相对简单的实现方式,尤其是使用zsh,因为它已经支持chpwd钩子和$chpwd_functions数组。但是,正如人们所说,细节决定成败1

因此,在开始自己的实践之前,我想我应该问:有人知道这个想法的成熟实现吗?

或者,除了chpwd等人之外,是否zsh提供其他有助于实现这样的事情的工具?特别是,它是否为封装/保存/恢复环境提供任何支持? (我正在考虑R环境对象的一些东西,但不仅包括变量,还包括例如别名、选项等)


FWIW,我知道 Python 的virtualenv,它与本文中描述的想法共享一些功能,但当然,这仅限于与 Python 相关的设置。此外,它还会创建一个新的“状态变量”,如果您愿意的话,“当前虚拟环境”,正交(而不是包含在)“当前工作目录”状态变量。


1一旦人们更仔细地研究这一问题,很快就会遇到一些重要的问题。例如:如果cd'ing to/my/projects/foo激活自定义环境,那么之后会发生什么cd /my/projects/foo/modules/bar?我们可以拥有由文件系统的树结构划分的嵌套自定义环境吗?符号链接怎么样?例如,如果/my/projects/foo/modules/bar实际上是 的符号链接怎么办/my/shared/modules/bar?或者,如果我执行/my/projects/foo/some_programwhile $PWDis /tmp,那么结果进程的环境应该是什么?等等,等等,等等。我并不认为这些问题一定是棘手的,但我确实发现它们至少不是完全微不足道的。

答案1

有成熟的工具旨在为特定目录设置环境变量。

与为此设计的其他工具相比,direnv是其中最好的。主要好处之一是它支持卸下当您退出该目录时,更改环境变量。

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

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

  • direnv是用 Go 编写的,快点与用 Python 编写的对应版本相比
  • direnv支持卸下当您从特定目录退出时使用环境变量
  • direnv覆盖许多贝壳

类似项目

  • 环境模块- 最古老(以一种好的方式)的环境加载系统之一
  • 自动环境- 轻的;不支持卸载;用Python写的很慢
  • zsh-autoenv- autoenv 和的功能丰富的混合物智能CD:进入/离开事件、嵌套、隐藏(仅限 Zsh)。
  • 阿斯达夫- 具有插件系统的纯 bash 解决方案

相关内容