Python Popen:将环境变量传递给使用sudo作为另一个用户运行的命令

时间:2017-11-01 09:24:36

标签: python linux

subprocess.Popen()函数有一个“env”参数。但它似乎与sudo没有预期的效果。这是我在交互式Python shell中执行此操作时得到的结果:

import subprocess
env={"CVS_RSH":"ssh"}
command = "sudo -u user cvs -d user@1.8.7.2:/usr/local/ncvs co file.py"
p = subprocess.Popen(command, stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,env=env,shell=True)
(command_output, error_output) = p.communicate()
p.wait()

1
>>> error_output
b'cvs [checkout aborted]: cannot exec rsh: No such file or 
directory\ncvs [checkout aborted]: end of file from server (consult 
above messages if any)\n'

这个消息令人分心,所以让我解释一下。我被迫使用古老的CVS,环境变量告诉它使用ssh连接到服务器,而不是默认情况下可能是rsh。它还需要一个名为CVS_ROOT的环境变量,但幸运的是有一个“-d”选项,但我所知道的CVS_RSH没有。

有趣的是,如果我这样做:

command = "sudo -u user echo $CVS_RSH"
env={"CVS_RSH":"something_else"}
p = subprocess.Popen(command, stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE,env=env,shell=True)
(command_output, error_output) = p.communicate()
p.wait()

0
>>> command_output
b'something_else\n'

也许这有效,因为echo实际上并不是作为子进程启动的?是否可以将环境传递给使用sudo作为另一个用户执行的进程?

1 个答案:

答案 0 :(得分:1)

使用env参数似乎不太可能。解决方案似乎只是像在shell上那样传递环境,例如:

command = "sudo -u user CVS_RSH=ssh 
    CVSROOT=:ext:user@2.8.7.2:/usr/local/ncvs cvs co dir/file.py"
p = subprocess.Popen(command, stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE,env=env,shell=True)

奇怪的是,如果我在Python CGI脚本中这样做,我可以看到:

  

cvs [checkout aborted]:不能执行ssh:Permission denied

     

cvs [checkout aborted]:来自服务器的文件结尾(如果是,请查阅以上消息)   任何)

但是如果我尝试使用交互式Python shell,它就会超过这个,所以它必须是另一个奇怪的(因为用户有权ssh)问题,与此问题无关。