how to activate virtualenv created by pyenv in bash script?
Asked Answered
D

2

5

I need to write a script to start gunicorn + django site which developed with pyenv the script is something like

#!/bin/bash
                                                                                
pyenv activate .ve
pyenv exec gunicorn config.wsgi:application --name mini2 --workers 8 \
--workers 8 --bind=unix:/tmp/run/mini2.socket \
--log-level=debug --log-file=-

and the error message

2021-12-06 14:09:00 [mini2@s017 mini2]$ ./prodution.sh 

Failed to activate virtualenv.

Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.

2021-12-06 14:09:55 [mini2@s017 mini2]$ 

I can run the script line by line. so there must be something wrong in the script , but I have no clue what's going wrong.

I had already append couple lines about pyenv in my bashrc

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
 eval "$(pyenv init -)"
fi

so is there anyway to activate virtualenv create by pyenv in bash script ? any suggestions ??

update:

according to Failed to activate virtualenv with pyenv

I update my .bashrc

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
#if command -v pyenv 1>/dev/null 2>&1; then
# eval "$(pyenv init -)"
#fi

but still not working.

my test script
#!/bin/bash

pyenv activate .ve

and the error 

Failed to activate virtualenv.

Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.
Dardanelles answered 6/12, 2021 at 6:25 Comment(4)
Try python - Failed to activate virtualenv with pyenv - Stack Overflow (see also python - Using 'pyenv activate' in a Dockerfile - Stack Overflow) . You didn't have all of the commands.Soldierly
activate should only be relevant for interactive shells. Your pyenv exec should work without the activate. ~/.bashrc is also only used by interactive shells.Bazar
@Bazar so , what's your suggestion ? how to update the script ?Dardanelles
Interesting, I seem to have the same problem but I never noticed because I activate my environment by sourcing activate directly source .ve/bin/activateKirkwood
G
5

Instead of using

${PYENV_ROOT}/versions/<venv name>/bin/python script.py

as suggested in other answers, you could activate the environment "manually":

. ${PYENV_ROOT}/versions/<venv name>/bin/activate
python script.py

Note that the dot before ${PYENV_ROOT} is equal to the source command.

This has the benefit of leaving python script.py as the command line instead of /home/<user>/<pyenv root>/versions/<venv name>/bin/python script.py, which could be helpful in htop for example.

This would mean that replacing

pyenv activate .ve

with

. ${PYENV_ROOT}/versions/.ve/bin/activate

would fix your issue, provided that .ve is the name of the virtual environment.

Giraud answered 2/11, 2022 at 13:37 Comment(0)
M
3

There is no need to pyenv activate the virtual environment in your script. Because of how virtual environments work [1], you need only use the absolute path to the Python interpreter binary. You can confirm this path using $ pyenv which python whilst your environment is activated. The most substantive thing that pyenv activate does is prepend the interpreter binary to your PATH such that python, python3, etc. will resolve to it [2]. The pyenv initialization commands in your .bashrc only serve to enable shell auto-completion, rehash shims, and define a pyenv shell function [3].

TLDR:

#!/bin/bash

"${PYENV_ROOT}/versions/<venv name>/bin/python" script.py
Misfeasance answered 15/4, 2022 at 19:3 Comment(3)
Thanks for this useful answer, but the double quotes convert the command into a string.Giraud
@DanielF I'm not certain in what context you are referring to, but I clarified the example above to make it clear that it is BASH. If you omitted the quotes and the expanded path had spaces, it would not be interpreted correctly by the shell.Misfeasance
My apologies, my mistake. I tried it once with quotes and it didn't work so I removed them, I can't remember exactly what I was executing, but my command should run inside gnu-screen like screen -AmdS test "${PYENV_ROOT}/versions/test-env/bin/python" test.py and I got an error. But I tried it again now and it works. I think I was in the wrong working directory or something. Thanks for making me check again.Giraud

© 2022 - 2024 — McMap. All rights reserved.