The -s
argument to the python interpreter prevents sys.path
from having user directories:
-s Don't add user site directory to sys.path.
Setting the PYTHONNOUSERSITE
environment variable is another way to achieve the same result. Note that setting a user site directory in PYTHONPATH
and then calling a script with -s
"overrides" the "user site" removal.
If I do not control how a python script is invoked, is there an easy way to remove user directories in a python script or module? I could iterate over sys.path and remove any entries that start with os.environ["HOME"]
. Is that the right way? Will I miss any or maybe remove directories that I shouldn't (e.g., what if someone installed python in their home directory, maybe even in ~/.local/... somewhere?)? Is HOME
env var the right thing to look for? I don't see any sys.path.usersite
that I can use to seed the path scrubbing effort (but see Update 1).
Is there a way to scrub user site directories that's easier than adding that iteration blob at the top of all the python scripts?
A shebang line like so achieves this:
#!/usr/local/bin/python -s
But if one doesn't want to hard-code the path to the python interpreter, one can use this idiom:
#!/usr/bin/env python
Adding arguments (like -s
) to the above doesn't work, however, because of the way shebang lines are interpreted on most unix systems (see Update 2):
env: python -s: No such file or directory
There's two subtle variations to this question:
(1) How to emulate what -s
does when your script was not invoked with -s
(including allowing user site directories if they are in PYTHONPATH
)? Maybe the best way(?) for this variation is:
#!/bin/sh
exec python -s << eof
... python code...
eof
Edit The above fails if you want to pass args. This may work better:
#!/bin/sh
exec python -s - "$@" << "eof"
... python code...
eof
Notice the quoted "eof" to avoid having the shell try to do expansions and substitions in the here document body.
As a side note: that also helps if I want the python -S
functionality (which does not have an environment variable knob equivalent) or other python option arguments.
(2) How to emulate -s
regardless of PYTHONPATH
(i.e., remove user site directories even if they are in PYTHONPATH)?
I guess what I was hoping for was a sys variable that points to the user site dir. But I couldn't find one.
Update 1: Thanks to Blender's comment - the variable is in the site module: site.USER_SITE
. So you can iterate over sys.path looking for entries rooted in that directory (could have .egg files in your USER_SITE and to emulate -s, you would need to remove those as well).
Update 2: Using env -S
is another solution. It allows you to pass arguments to the command spawned by env(1)
in a shebang line. FreeBSD has had -S for years (since 6.0). Linux systems that use coreutils (most) have it as of coreutils 8.30 1. It will take a while for Linux distros to get that version of coreutils, so depending on it for portable scripting is probably not prudent yet (now = 2019).
#!/usr/bin/env -S python -s
p.s. See also this older similar thread.