用Python脚本使用sudo
我试图写一个小脚本来挂载一个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)
我的Python版本是2.6
sudoPassword = 'mypass' command = 'mount -t vboxsf myfolder /home/myuser/myfolder' p = os.system('echo %s|sudo -S %s' % (sudoPassword, command))
试试这个,让我知道如果它的作品。 🙂
和这个:
os.popen("sudo -S %s"%(command), 'w').write('mypass')
许多答案着重于如何使你的解决scheme工作,而很less有人提出你的解决scheme是一个非常糟糕的方法 。 如果你真的想“练习学习”,为什么不练习使用好的解决scheme呢? 硬编码您的密码正在学习错误的方法!
如果你真的想要的是一个无密码的mount
量,也许sudo
根本就不需要! 那么我可以build议其他方法吗?
-
用mensibuild议使用
/etc/fstab
。 使用选项user
和noauto
让普通用户挂载该卷。 -
使用
Polkit
进行无密码操作:使用<allow_any>yes</allow_any>
为脚本configuration.policy
文件,然后放在/usr/share/polkit-1/actions
-
编辑
/etc/sudoers
以允许你的用户使用sudo
而不用input你的密码。
以上所有都允许使用无密码的root权限,但不要求您对密码进行硬编码。 select任何方法,我可以更详细地解释它。
将密码传递给sudo
的标准input:
#!/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]
注意:你可以configuration无密码的sudo或SUDO_ASKPASS
命令,而不是在源代码中硬编码你的密码。
subprocess.Popen
进程subprocess.Popen
创build一个进程并打开pipe道和东西。 你在做什么是:
- 开始一个进程
sudo -S
- 启动一个进程
mypass
- 启动进程
mount -t vboxsf myfolder /home/myuser/myfolder
这显然不起作用。 你需要把论据传递给Popen。 如果你看看它的文档 ,你会注意到第一个参数实际上是一个参数列表。
有时需要回车:
os.popen("sudo -S %s"%(command), 'w').write('mypass\n')
请尝试模块pexpect。 这是我的代码:
import pexpect remove = pexpect.spawn('sudo dpkg --purge mytool.deb') remove.logfile = open('log/expect-uninstall-deb.log', 'w') remove.logfile.write('try to dpkg --purge mytool\n') if remove.expect(['(?i)password.*']) == 0: # print "successfull" remove.sendline('mypassword') time.sleep(2) remove.expect(pexpect.EOF,5) else: raise AssertionError("Fail to Uninstall deb package !")
我知道总是不要在脚本中硬编码sudo密码。 但是,由于某种原因,如果您没有权限修改/etc/sudoers
或更改文件所有者,则Pexpect是可行的select。
这是一个Python函数sudo_exec
供您参考:
import platform, os, logging import subprocess, pexpect log = logging.getLogger(__name__) def sudo_exec(cmdline, passwd): osname = platform.system() if osname == 'Linux': prompt = r'\[sudo\] password for %s: ' % os.environ['USER'] elif osname == 'Darwin': prompt = 'Password:' else: assert False, osname child = pexpect.spawn(cmdline) idx = child.expect([prompt, pexpect.EOF], 3) if idx == 0: # if prompted for the sudo password log.debug('sudo password was asked.') child.sendline(passwd) child.expect(pexpect.EOF) return child.before
-
在sudo命令中使用-S选项,它告诉从“stdin”而不是terminal设备读取密码。
-
告诉Popen从PIPE读取stdin。
-
通过使用它作为参数来传递方法,将密码发送到进程的stdin PIPE。 不要忘记在密码末尾添加一个新的行字符'\ n'。
sp = Popen(cmd , shell=True, stdin=PIPE) out, err = sp.communicate(_user_pass+'\n')