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作为另一个用户执行的进程?
答案 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)问题,与此问题无关。