This document is a WORK IN PROGRESS.
This is just a quick personal cheat sheet: treat its contents with caution!
direnv¶
direnv
is an extension for your shell. It augments existing shells with a new feature that can
load and unload environment variables depending on the current directory.
Reference(s)
- https://github.com/direnv/direnv
- https://github.com/direnv/direnv/tree/master/man
- https://github.com/direnv/direnv/blob/master/man/direnv.1.md
- https://github.com/direnv/direnv/blob/master/man/direnv.toml.1.md
- https://github.com/direnv/direnv/blob/master/man/direnv-stdlib.1.md
- https://github.com/direnv/direnv/blob/master/man/direnv-fetchurl.1.md
Table of contents¶
Install¶
For direnv
to work properly it needs to be hooked into the shell. Each shell has its own
extension mechanism. Once the hook is configured, restart your shell for direnv
to be activated.
Add the following line at the end of $HOME/.bashrc
(or
${BDOTDIR:-${HOME/.config/bdotdir}}/.bashrc
or wherever):
$ vi $HOME/.bashrc # or ${BDOTDIR:-${HOME/.config/bdotdir}}/.bashrc or wherever
> ...
> eval "$(direnv hook bash)"
Make sure it appears even after rvm, git-prompt and other shell extensions that manipulate the prompt.
Add the following line at the end of ${ZDOTDIR:-${HOME}}/.zshrc
(or wherever):
Add the following line at the end of $HOME/.config/fish/config.fish
(or wherever):
Fish supports 3 modes you can set with the global environment variable direnv_fish_mode
:
$ set -g direnv_fish_mode eval_on_arrow # trigger direnv at prompt, and on every arrow-based directory change (default)
$ set -g direnv_fish_mode eval_after_arrow # trigger direnv at prompt, and only after arrow-based directory changes before executing command
$ set -g direnv_fish_mode disable_arrow # trigger direnv at prompt only, this is similar functionality to the original behavior
Add the following line at the end of the ~/.cshrc
file:
Config¶
See https://github.com/direnv/direnv/blob/master/man/direnv.toml.1.md.
Use¶
$ echo "Create a new folder for demo purposes."
$ mkdir ~/my-project
$ cd ~/my-project
$ echo "Show that the FOO environment variable is not loaded."
$ echo ${FOO-nope}
nope
$ echo "Create a new .envrc. This file is bash code that is going to be loaded by direnv."
$ echo export FOO=foo > .envrc
.envrc is not allowed
$ echo "The security mechanism didn't allow to load the .envrc. Since we trust it, let's allow its execution."
$ direnv allow .
direnv: reloading
direnv: loading .envrc
direnv export: +FOO
$ echo "Show that the FOO environment variable is loaded."
$ echo ${FOO-nope}
foo
$ echo "Exit the project."
$ cd ..
direnv: unloading
$ echo "And now FOO is unset again."
$ echo ${FOO-nope}
nope
$ echo "Show how to unset/block direnv (and unset all associated environment variables)."
$ cd my-project
direnv: loading ...
$ echo ${FOO-nope}
foo
$ direnv deny .envrc
direnv: error ~/my-project/.envrc is blocked. Run `direnv allow` to approve its content
$ echo ${FOO-nope}
nope
Before each prompt, direnv
checks for the existence of a .envrc
or .env
file in the current
and parent directories. If the file exists (and is authorized), it is loaded into a bash sub-shell
and all exported variables are then captured by direnv
and then made available to the current
shell.
If both .envrc
and .env
files exists, the .envrc
will always be chosen first.
It supports hooks for all the common shells like bash
, zsh
, tcsh
and fish
. This allows
project-specific environment variables without cluttering the ~/.profile
file.
Because direnv
is compiled into a single static executable, it is fast enough to be unnoticeable
on each prompt. It is also language-agnostic and can be used to build solutions similar to rbenv
,
pyenv
and phpenv
.
.envrc
also has the advantage of accepting a set of utility functions enhancing the direnv
experience, see https://github.com/direnv/direnv/blob/master/man/direnv-stdlib.1.md.
If this cheat sheet has been useful to you, then please consider leaving a star here.