New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why is direnv messing with existing variables? #82
Comments
Hi @pdf, thanks for reporting. It's two different issues that issue from the same direnv mechanism. direnv serializes the old environment in the DIRENV_BACKUP environment variable, runs a bash sub-shell to load the .envrc and exports the diff between the old and new environment in the shell. Unloading the environment just means restoring the content that's in the DIRENV_BACKUP. In the first case it's an unidentified issue with bash that I also saw on #81. In some condition bash seems to be changing the COMP_WORDBREAKS variable in the subshell. It shouldn't because the subshell bash is executed with I believe the second case only happens when you start tmux from withing a loaded .envrc environment. The backup has already happened before tmux is started. The tmux+bash subshell is now loaded with both the old DIRENV_BACKUP and the new TMUX_* variables introduced by tmux. When you cd .. outside of your project inside tmux it will restore the DIRENV_BACKUP environment and remove the TMUX_* variables who are not part of it. |
One solution for tmux would be to use a wrapper. Add this script somewhere in your PATH under #!/usr/bin/env bash
pwd=$PWD
cd /
eval "$(direnv export bash)"
cd $pwd
exec tmux "$@"
Then |
Thanks @zimbatm. I believe you're right about the problem only occurring when starting tmux from within an existing .envrc environment. The workaround is essentially working, but tmux likes to call itself a lot, so direnv does a lot of reloading with the alias in place. I may be missing some understanding here, but why is direnv doing anything with variables that it's not being told to modify? That just seems wrong to me. |
@pdf the problem is that since we use bash to run the |
@pwaller I'm not entirely convinced that's the best that can be done. An example implementation that would behave correctly might be to parse the .envrc and perform individual actions that could be tracked inside direnv. There may be other ways of tracking stuff, too. With that aside, why is DIRENV_BACKUP exported? Why do we ever want that in subshells? This particular issue (and I suspect others of similar provenance) wouldn't occur if it wasn't exported. |
@pdf, I didn't mean to imply it was the best one could theoretically achieve, however, given the constraints on the project and the fact we currently use bash in the way it is used I would say it is (probably) unreasonable to implement, hook or otherwise hack a shell interpreter to tell us whenever an environment variable is set. That's a good thought about |
The reason why direnv works like that is because it was simple to implement @pdf if DIRENV_BACKUP is unset it's not possible to revert the env changes.
|
I wasn't suggesting unsetting it, just not exporting it... however, I see below why that is not possible.
That is indeed problematic. I've tried having a quick browse of the code, but I'm struggling to put all the pieces together on how this works. Perhaps this can be attacked from another angle - what is it about tmux that triggers an unload, even though DIRENV_DIR hasn't changed? |
I'm going to change direnv to only track and restore variables that have been changed in the |
This commit changes how direnv works and the terminal needs to be restarted. Previously any changed environment would be reverted when exiting a folder that contains an .envrc. This changes the behavior to only restore variables that where changed inside the .envrc.
^ this commit should fix the TMUX issue. All tests are passing but since it changes how direnv works you need to restart your shell just to be sure. @pdf if you can test it it would be great. I'm going to merge it in a week or so. |
This commit changes how direnv works and the terminal needs to be restarted. Previously any changed environment would be reverted when exiting a folder that contains an .envrc. This changes the behavior to only restore variables that where changed inside the .envrc.
Sorry for the delay in testing - this time of year is hectic. This fix looks great, thanks! |
Ok merged into master, direnv release following soon. |
I have a
.envrc
:So, I would expect direnv to modify nothing but PATH when loading that file. Instead I get:
Why is it deleting COMP_WORDBREAKS?
And worse, when I'm in tmux:
Now it's deleting all the TMUX vars (I need to know if I'm inside TMUX!) and worse still, it's overwriting my TERM, which breaks drawing via ncurses, amongst other nastiness.
I don't understand what's going on here - why is direnv messing with anything that's not in the
.envrc
?The text was updated successfully, but these errors were encountered: