def _emulate_shell_environ(): import os import sys import time import subprocess if sys.version_info[0] > 2: env = os.environb else: env = os.environ split_char = b'=' # Start 'login -qf $LOGIN' in a pseudo-tty. The pseudo-tty # is required to get the right behavior from the shell, without # a tty the shell won't properly initialize the environment. # # NOTE: The code is very carefull w.r.t. getting the login # name, the application shouldn't crash when the shell information # cannot be retrieved master, slave = os.openpty() pid = os.fork() try: login = os.getlogin() except AttributeError: try: login = os.environ['LOGNAME'] except KeyError: login = None if login is not None: if pid == 0: # Child os.close(master) os.setsid() os.dup2(slave, 0) os.dup2(slave, 1) os.dup2(slave, 2) os.execv('/usr/bin/login', ['login', '-qf', login]) os._exit(42) else: # Parent os.close(slave) # Echo markers around the actual output of env, that makes it # easier to find the real data between other data printed # by the shell. os.write(master, b'echo "---------";env;echo "-----------"\r\n') os.write(master, b'exit\r\n') time.sleep(1) data = [] b = os.read(master, 2048) while b: data.append(b) b = os.read(master, 2048) data = b''.join(data) os.waitpid(pid, 0) in_data = False for ln in data.splitlines(): if not in_data: if ln.strip().startswith(b'--------'): in_data = True continue if ln.startswith(b'--------'): break try: key, value = ln.rstrip().split(split_char, 1) except: pass else: env[key] = value _emulate_shell_environ()