在Python脚本中使用sudo

Rom*_*dgz 31 python shell subprocess

我正在尝试编写一个小脚本来在每次执行脚本时挂载VirtualBox共享文件夹.我想用Python做,因为我正在尝试用它来学习脚本.

问题是我需要权限才能启动mount命令.我可以将脚本作为sudo运行,但我更喜欢它自己创建sudo.

我已经知道将密码写入.py文件是不安全的,但我们谈的是一个根本不重要的虚拟机:我只想点击.py脚本并让它运行起来.

这是我的尝试:

#!/usr/bin/env python
import subprocess

sudoPassword = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'

subprocess.Popen('sudo -S' , shell=True,stdout=subprocess.PIPE)
subprocess.Popen(sudoPassword , shell=True,stdout=subprocess.PIPE)
subprocess.Popen(command , shell=True,stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

我的python版本是2.6

Mes*_*ion 50

许多答案都集中在如何使您的解决方案工作,而很少有人建议您的解决方案是一个非常糟糕的方法.如果你真的想"练习学习",为什么不练习使用好的解决方案呢?硬编码密码正在学习错误的方法!

如果你真的想要的是一个无密码的mount该卷,也许sudo并不需要在所有!我可以建议其他方法吗?

  • 使用/etc/fstabMENSI建议.使用选项usernoauto让常规用户挂载该卷.

  • 使用Polkit无密码的行为:配置.policy文件为您的脚本<allow_any>yes</allow_any>,并在下降/usr/share/polkit-1/actions

  • 编辑/etc/sudoers以允许您的用户sudo无需输入密码即可使用.

以上所有内容都允许无密码root权限,不需要您对密码进行硬编码.选择任何方法,我可以更详细地解释它.

至于为什么硬编码密码是一个非常糟糕的主意,这里有一些很好的链接供进一步阅读:

  • 最后一点,编辑 sudoers 在 https://askubuntu.com/a/155827/42796 中有很好的解释 (2认同)
  • 对新手来说,解释_why_硬编码用户密码是_非常糟糕的方法_可能会有所帮助。 (2认同)

Ani*_*nge 30

sudoPassword = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'
p = os.system('echo %s|sudo -S %s' % (sudoPassword, command))
Run Code Online (Sandbox Code Playgroud)

试试这个,让我知道它是否有效.:-)

还有这个:

os.popen("sudo -S %s"%(command), 'w').write('mypass')

  • 你真的不应该使用这样一行`os.system('echo%s | sudo -S%s'%(sudoPassword,command))`,因为它带来了一个安全漏洞.通过将密码写为shell命令,可以通过`.bash_history`文件和运行`history` shell命令访问它.始终通过stdin传递密码,因为它是更安全的方法 (10认同)
  • 这个答案有 3 票反对,我正在堆积另一票。**这段代码增加了两个漏洞**:1)在进程表中记录任何其他进程都可以看到的密码,如上所述,而且2)**shell注入**,如果其他东西可以设置该密码怎么办,并将其设置为 `foo$(rm -rf /*)bar` ?你看到这个问题了吗? (3认同)

jfs*_*jfs 15

要将密码传递给sudostdin:

#!/usr/bin/env python
from subprocess import Popen, PIPE

sudo_password = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'.split()

p = Popen(['sudo', '-S'] + command, stdin=PIPE, stderr=PIPE,
          universal_newlines=True)
sudo_prompt = p.communicate(sudo_password + '\n')[1]
Run Code Online (Sandbox Code Playgroud)

注意:您可以配置无密码sudo或SUDO_ASKPASS命令,而不是在源代码中硬编码密码.


小智 5

  • 在 sudo 命令中使用 -S 选项,它告诉从“标准输入”而不是终端设备读取密码。

  • 告诉 Popen 从 PIPE 读取标准输入。

  • 通过将密码用作通信方法的参数,将密码发送到进程的标准输入管道。不要忘记在密码末尾添加一个新行字符“\n”。

sp = Popen(cmd , shell=True, stdin=PIPE)
out, err = sp.communicate(_user_pass+'\n')   
Run Code Online (Sandbox Code Playgroud)