diff --git a/.gitignore b/.gitignore index c10666e..3505b32 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .idea *.pyc +build/ +elevate.egg-info/ diff --git a/README.rst b/README.rst index ea6087c..14e100a 100644 --- a/README.rst +++ b/README.rst @@ -41,4 +41,8 @@ new console window. To suppress this window, use ``elevate(show_console=False)``. On Linux and macOS, graphical prompts are tried before ``sudo`` by default. To -prevent graphical prompts, use ``elevate(graphical=False)``. +prevent graphical prompts, use ``elevate(graphical=False)``. + +For macOS non-graphical prompts (i.e. sudo) you can use +``elevate(graphical=False, preserve_env=True)`` and the relaunch as root will +preserve the shell environment. diff --git a/elevate/.gitignore b/elevate/.gitignore new file mode 100644 index 0000000..8f7dc02 --- /dev/null +++ b/elevate/.gitignore @@ -0,0 +1 @@ + ..rfbrost.SOFTWARE.PYTHON.ELEVATE.elevate diff --git a/elevate/__init__.py b/elevate/__init__.py index 601623c..c77608e 100644 --- a/elevate/__init__.py +++ b/elevate/__init__.py @@ -1,7 +1,7 @@ import sys -def elevate(show_console=True, graphical=True): +def elevate(show_console=True, graphical=True, preserve_env=False): """ Re-launch the current process with root/admin privileges @@ -19,5 +19,6 @@ def elevate(show_console=True, graphical=True): from elevate.windows import elevate else: from elevate.posix import elevate - elevate(show_console, graphical) + + elevate(show_console, graphical, preserve_env) diff --git a/elevate/posix.py b/elevate/posix.py index 06d2a81..e0b8ece 100644 --- a/elevate/posix.py +++ b/elevate/posix.py @@ -1,6 +1,7 @@ import errno import os import sys + try: from shlex import quote except ImportError: @@ -12,7 +13,7 @@ def quote_shell(args): def quote_applescript(string): - charmap = { + charmap: str = { "\n": "\\n", "\r": "\\r", "\t": "\\t", @@ -22,12 +23,12 @@ def quote_applescript(string): return '"%s"' % "".join(charmap.get(char, char) for char in string) -def elevate(show_console=True, graphical=True): +def elevate(show_console=True, graphical=True, preserve_env=False): if os.getuid() == 0: return - args = [sys.executable] + sys.argv - commands = [] + args: str = [sys.executable] + sys.argv + commands: list = [] if graphical: if sys.platform.startswith("darwin"): @@ -44,11 +45,15 @@ def elevate(show_console=True, graphical=True): commands.append(["gksudo"] + args) commands.append(["kdesudo"] + args) - commands.append(["sudo"] + args) + if preserve_env: + pythonpath = os.environ.get('PYTHONPATH', '') + commands.append(["sudo", "-E", f"PYTHONPATH={pythonpath}"] + args) + else: + commands.append(["sudo"] + args) for args in commands: try: os.execlp(args[0], *args) except OSError as e: if e.errno != errno.ENOENT or args[0] == "sudo": - raise + raise