You don't really have a problem with subprocess here. Subprocess is getting passed the environment from your current environment, so when you "echo $USER", it's reporting the user from the current environment.
See what happens when you change the command to whoami
, which actually checks your UID:
My python shell is running as root:
>>> print os.getuid()
0
But changing the command being run outputs the correct new user:
>>> cmd = "whoami"
>>> proc = subprocess.Popen(cmd, preexec_fn=demote(1000), stdout=subprocess.PIPE, shell=True)
>>> output = proc.communicate()[0]
>>> print output
voodoonofx
If you really want to modify the environment to be that user, you could pass a new dictionary to the Popen call. See the env keyword passed with help(subprocess.Popen):
__init__(self, args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
Create new Popen instance.