Reputation: 190
I am trying to activate a python environment and installing some packages using pip in a bash file. It succeeds to install in the environment but also installs globally on my mac, and I don't understand why.
script.sh:
#!/bin/bash
source '<absolute path>/venv/bin/activate'
which pip
pip install psutil
pip list
output:
$ ./script.sh
<absolute path>/venv/bin/pip
...
Package Version
---------------- ---------
pip 19.0.3
psutil 5.6.3
setuptools 41.0.1
wheel 0.33.1
But, in another terminal without the virtual environment it also gets installed:
$ which pip
/usr/local/opt/python/libexec/bin/pip
$ pip list
Package Version
---------------- ---------
pip 19.0.3
psutil 5.6.3
setuptools 41.0.1
wheel 0.33.1
If i type the commands in the script one by one in the terminal, it works as expected.
What am i missing?
edit:
If i run pip freeze | xargs pip uninstall -y
(either in env or globally) it removes the packages both in the virtualenv and globally.
If i run the script again and I list the content in 'site-packages' ls venv/lib/python3.7/site-packages
the installed package is not there, so my 'venv/bin/pip' is somehow pointing to my global 'site-packages'?
edit2:
I found a way to reproduce the behaviors.
1. create an environment python -m venv venv_test
2. activate the environment . venv_test/bin/activate
3. edit source '<absolute path>/venv_test/bin/activate'
in script.sh
4. run script ./script.sh
Why does this make pip install globally?
If i skip 2. it works as expected.
Upvotes: 3
Views: 5460
Reputation: 1079
Running this in a bash script runs the commands in a different shell, then returns you to your original shell. Running source <path>/bin/activate
runs this in you current shell, hence this works from the command line. Your bash script looks like:
#!/bin/bash
source "<absolute path>/venv/bin/activate"
which pip
pip install psutil
pip listenter code here
If you call this with source script.sh
this will run this in you current shell and should work as expected. Hope this helps. There is some other methods here:
https://stackoverflow.com/a/13122219/7473057
An example method for virtualenvs:
python -m venv venv_test
or virtualenv venv_test
source ./venv_test/bin/activate
(on cmd line) ./script.sh
, which has source "<absolute path>/venv/bin/activate"
removed.Alternatively, I think what you are after is a subshell, running everything inside, which is in the link above.
Upvotes: 5