virthualenv
virthualenv copied to clipboard
Cannot deactivate virthualenv inside screen/tmux
If I activate a virthualenv in a shell and then start screen or tmux, the virthualenv persists and I can use it as normal, as I would expect. However, I cannot deactivate it as the deactivate
function is not export
ed by bin/activate
. I would recommend export
ing that function, but I don't know if that would have other undesirable consequences, and I haven't yet had a chance to test it out.
I think we should either find a way to safely and robustly deactivate from within screen/tmux or at least make it explicit in the documentation that it can't be done.
I can say that adding export -f deactivate
somewhere after the definition of the function does make it available inside each screen/tmux window and appears to deactivate only within that shell.
ok, this one is hard.
first of all, after starting screen/tmux from inside virthualenv it does not work correctly (at least on my bash machine) - $PATH is not preserved, so it uses your bare/pre-virthualenv $PATH, so no cabal wrapper for you. you also lose fancy prompt, so it doesn't look correctly either.
export -f deactivate looks like a bash-specific thing, from bash --posix it works just like without that command. zsh displays deactivate's source code. so it looks, like it only works in bash and you still get broken virthualenv inside screen/tmux.
Python's virtualenv fails in the same way (and they have much bigger user base) and I don't know posix shell programming (or even bash) to make it work with screen/tmux, I'll have to leave it be.
The only idea I have is to add info about it to README and provide wrappers for screen and tmux binaries, that display big fat warning, that virtual environment will not work inside screen/tmux, wait for a key and then run screen/tmux, what do you think about it?
Doing some quick googling reveals that the virtualenv community hasn't solved this problem either, which is unfortunate for us.
I'm not a big fan of wrapping screen/tmux as that might have unforeseeable consequences for some people (it could interfere with custom aliases, wouldn't work if screen/tmux as called by absolute path or indirectly via some other command). I would say that you need to test for screen/tmux before providing wrappers for them. Otherwise, the user might think a command is installed when in fact it's really just the wrapper.
If you do wrap screen/tmux, it may be a better idea to call deactivate and then tell the user to manually call activate in each terminal. This solution seems to generate the fewest surprises for the user. They only get the one warning at the beginning instead of a warning and then a bunch of other things not functioning as expected.
it could interfere with custom aliases
hmm, only if those aliases are defined earlier using something like which screen
wouldn't work if screen/tmux as called by absolute path
I think it's really not-unixy to call binaries by hardcoded paths
I would say that you need to test for screen/tmux before providing wrappers for them.
good point.
it may be a better idea to call deactivate and then tell the user to manually call activate in each terminal.
great idea! seems like the best solution.
I wrote a simple wrapper for tmux command:
# virtualenv does not work correctly when tmux is run inside virtualenv.
# this function is a wrapper around tmux command that deactivates virtualenv
# before running tmux and reactivates it again. --cenkalti
tmux()
{
local current_env=""
if [ "$VIRTUAL_ENV" != "" ]; then
current_env="$VIRTUAL_ENV"
deactivate
fi
command tmux "$@"
local ret=$?
if [ "$current_env" != "" ]; then
workon $(basename $current_env)
fi
return $ret
}
It seems commands after tmux execution is executed after the tmux subprocess is detached or exited. So I wrote that part in bashrc directly instead. The following code works for me:
(write in ~/.bashrc, for instance)
if [ "$current_env" != "" ]; then
workon $(basename $current_env)
unset current_env
fi
tmux()
{
current_env=""
if [ "$VIRTUAL_ENV" != "" ]; then
current_env="$VIRTUAL_ENV"
deactivate
export current_env
fi
command tmux "$@"
}
The same way is available for screen, too.