70

How to install a package in the standard python environment i.e. /usr/local/lib/python2.7/dist-packages using pip and make this new package available for all the users without using virtualenv?

By using the following, the package is installed with root permissions only:

$ sudo pip install loremipsum
Downloading/unpacking loremipsum
  Downloading loremipsum-1.0.5.tar.gz
  Running setup.py (path:/tmp/pip_build_root/loremipsum/setup.py) 
  egg_info for package loremipsum
    
Installing collected packages: loremipsum
  Running setup.py install for loremipsum
    
Successfully installed loremipsum
Cleaning up...

Proof:

$ python -c 'import loremipsum'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named loremipsum

$ sudo python -c 'import loremipsum'

$ pip install loremipsum
Requirement already satisfied (use --upgrade to upgrade): loremipsum in 
/usr/local/lib/python2.7/dist-packages
Cleaning up...

$ cowsay sad
 _____
< sad >
 -----
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Please do not advise me to use apt-get install python-... instead. I would like to know what is my mistake and how to use pip correctly.

$ python --version
Python 2.7.6
$ pip --version
pip 1.5.4 from /usr/lib/python2.7/dist-packages (python 2.7)
$ uname -a
Linux _ 3.19.0-32-generic #37~14.04.1-Ubuntu SMP _ x86_64 GNU/Linux

EDIT

I guess the problem is because pip does not allow the group and everyone to read the installed stuff:

$ sudo pip uninstall loremipsum
Uninstalling loremipsum:
  /usr/local/lib/python2.7/dist-packages/loremipsum-1.0.5.egg-info
  /usr/local/lib/python2.7/dist-packages/loremipsum/__init__.py
  /usr/local/lib/python2.7/dist-packages/loremipsum/__init__.pyc
  /usr/local/lib/python2.7/dist-packages/loremipsum/default/dictionary.txt
  /usr/local/lib/python2.7/dist-packages/loremipsum/default/sample.txt
  /usr/local/lib/python2.7/dist-packages/loremipsum/generator.py
  /usr/local/lib/python2.7/dist-packages/loremipsum/generator.pyc
Proceed (y/n)? y
  Successfully uninstalled loremipsum

$ sudo pip install loremipsum
Downloading/unpacking loremipsum
  Downloading loremipsum-1.0.5.tar.gz
  Running setup.py (path:/tmp/pip_build_root/loremipsum/setup.py) 
  egg_info for package loremipsum
    
Installing collected packages: loremipsum
  Running setup.py install for loremipsum
    
Successfully installed loremipsum
Cleaning up...
$ sudo ls -al /usr/local/lib/python2.7/dist-packages/loremipsum
total 60
drwxr-s---  3 root staff  4096 Apr 27 22:06 .
drwxrwsr-x 18 root staff  4096 Apr 27 22:06 ..
drwxr-s---  2 root staff  4096 Apr 27 22:06 default
-rw-r-----  1 root staff 16182 Apr 27 22:06 generator.py
-rw-r-----  1 root staff 16323 Apr 27 22:06 generator.pyc
-rw-r-----  1 root staff  6130 Apr 27 22:06 __init__.py
-rw-r-----  1 root staff  6869 Apr 27 22:06 __init__.pyc
nowox
  • 25,978
  • 39
  • 143
  • 293
  • What is the output of `python --version` and `pip --version`? – Ilya Popov Apr 27 '16 at 19:07
  • 1
    Yes, but, I don't want to separate it from the operating system... – nowox Apr 27 '16 at 19:15
  • @wRAR pip and virtualenv are for entirely different tasks. It's true that many people use pip and virtualenv in combination, but I don't think it's right to say that's the *correct* use. – wim Apr 27 '16 at 19:17
  • @wim, system packages interfere with the pip installations on *Nix systems, so yes, it is correct to say that the correct use of pip on Linux, Mac OS X, and others (such as Ubuntu, in particular) is within a virtualenv. – Alex Huszagh Apr 27 '16 at 19:22
  • 4
    No it's not. For example, if you deploy apps in docker containers you want to install to system directly. You have no use virtualenv because isolation is provided by cgroups, and you don't have to worry about system packages changing because you deploy the containers as immutable. This is a perfectly valid use of pip without using virtualenv. – wim Apr 27 '16 at 19:27
  • On a docker file with pip3 not using --user option did the trick, i.e; RUN pip3 install --no-cache-dir -r requirements.txt – ozgurozkanakdemirci Jan 03 '23 at 11:46

5 Answers5

46

You might have a wrong umask set as discussed here

From your last edit, I guess you umask is set to 027. Try to do

sudo pip uninstall loremipsum
umask 022
sudo pip install loremipsum
Community
  • 1
  • 1
nowox
  • 25,978
  • 39
  • 143
  • 293
  • 3
    For anyone interested `umask` is a command to set the default access rights for files / directories. See more [here](https://www.cyberciti.biz/tips/understanding-linux-unix-umask-value-usage.html) – Jeremy S. Aug 16 '17 at 15:12
  • 8
    Feels like a hack. Is this the official way? – robsch Feb 04 '19 at 14:51
  • @robsch no, have a look at the link of Jeremy. Check your umask with umask. – Timo Dec 31 '20 at 10:59
39

With Ubuntu 18.04, using the command sudo pip install stuff-name does not suffice, in my case, in order to install the modules in the global path (it keeps looking at the local-user python path).

Solution in my case

I have changed to the root user, and changed directory to its home. Then pip installation worked like expected and installs modules in the global path.

In detail I followed the nowox answer with a minor change (sudo su, changes to the root user), also see final note about umask 022:

sudo su
cd ~
umask 022
pip install what-you-like

Note: umask 022 command/row could be optional..., usually umask is already 022, that is the default one.

Fabiano Tarlao
  • 3,024
  • 33
  • 40
  • 1
    I just spent most of today trying to figure out why Flask was importable by Python on my server, except when WSGI was trying to import it. And it was because of this. Any idea why `pip` installs things in a hidden local dir now? – DaveTheScientist Oct 02 '19 at 21:05
  • 1
    I don't know, sorry, I never faced this WSGI, specific, case. – Fabiano Tarlao Oct 03 '19 at 06:58
  • @DaveTheScientist perhaps.. perhaps .. it depends on the fact that you run pip as the no-root user that is running the web server? – Fabiano Tarlao Oct 04 '19 at 06:30
  • @FabianoTarlao no, I ran pip as a different user (that had sudo access). It looks like this behavior is standard as of Python 2.6, but it was new to me: https://unix.stackexchange.com/questions/240037/why-did-pip-install-a-package-into-local-bin – DaveTheScientist Oct 08 '19 at 14:16
  • 2
    oh yes, this is the standard behaviour, for this reason my answer used, as first step, *sudo su*, because you need to go superuser/root in order to install stuff system-globally and not in local path (also cd ~ may be useful) – Fabiano Tarlao Oct 08 '19 at 19:29
16

For Ubuntu 18.04 try sudo -H pip install loremipsum.

-H is the short form of --set-home:

-H, --set-home
     Request that the security policy set the HOME environment variable
     to the home directory specified by the target user's password 
     database entry.  Depending on the policy, this may be the default
     behavior.

In other words, this executes the sudo command with the HOME environment var set to root's home.

SpinUp __ A Davis
  • 5,016
  • 1
  • 30
  • 25
Nathan McKaskle
  • 2,926
  • 12
  • 55
  • 93
10

Use the --target option when calling pip

pip install --target=/your/pyinstalldir loremipsum

The target directory must be a location writable by your user.

Note that this requires the regular user environment has the target directory present in the sys.path. One possible way to achieve that is by using the PYTHONPATH env var:

# /etc/profile.d/myenvvars.sh
export PYTHONPATH=/your/pyinstalldir
wim
  • 338,267
  • 99
  • 616
  • 750
  • 4
    To prevent erasing of previously defined variable, it's preferable to concatenate PYTHONPATH: export PYTHONPATH=$PYTHONPATH:/your/pyinstalldir – Vasin Yuriy Feb 12 '20 at 08:11
3

On Debian & Ubuntu 20.04

Debian, and by consequence Ubuntu, offer a --system option which might not be available on other GNU/Linux distributions. Here is how to use this:

$ pip --version
    pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)

$ pip install --help
    Install Options:
    --system    Install using the system scheme (overrides --user on Debian systems)

$ pip uninstall modulename
$ sudo pip install --system modulename

However, this will not work when pip was upgraded with pip from the PyPI repository:

$ pip --version
    pip 22.2.2 from /usr/local/lib/python3.8/dist-packages/pip (python 3.8)
Serge Stroobandt
  • 28,495
  • 9
  • 107
  • 102