如何从Python调用一个需要使用sudo(在stdin上还有密码)在stdin上提供数据的程序?
当我运行代码时,我遇到了这个错误“sudo:no tty present and no askpass program spcified”。这是第二个子流程调用的行,我尝试更改密码。用户创建得很完美,但密码不是,只是给出了给定的错误。我想做的是,在创建用户后,将向用户提供书面密码如何从Python调用一个需要使用sudo(在stdin上还有密码)在stdin上提供数据的程序?,python,python-2.7,shell,subprocess,Python,Python 2.7,Shell,Subprocess,当我运行代码时,我遇到了这个错误“sudo:no tty present and no askpass program spcified”。这是第二个子流程调用的行,我尝试更改密码。用户创建得很完美,但密码不是,只是给出了给定的错误。我想做的是,在创建用户后,将向用户提供书面密码 import subprocess def new(username, password): subprocess.call("echo passd23 | sudo -S adduser '{usernam
import subprocess
def new(username, password):
subprocess.call("echo passd23 | sudo -S adduser '{username}'".format(username=username), shell=True)
subprocess.call("echo passd23 | sudo '{username}':'{password}' | chpasswd".format(username=username, password=password), shell=True)
new("username", "password")
这是一种不好的做法,但比它所取代的做法更安全:
def new(username, password, sudopass):
p1 = subprocess.Popen(['sudo', '-S', 'adduser', username], stdin=subprocess.PIPE)
p1.communicate(sudopass)
if p1.retval != 0:
return False
p2 = subprocess.Popen(['sudo', '-S', 'chpasswd'], stdin=subprocess.PIPE)
p2.communicate('%s\n%s:%s\n' % (sudopass, username, password))
return p2.retval == 0
new('username', 'password', 'passd23')
值得注意的是:
- shell不会将任何用户提供的字符串解析为代码。
密码作为stdin传递,而不是在生成的命令行上,用户提供的用户名和密码尤其不会由shell计算sudo
- 使用
,stdin上会依次提供chpasswd
密码和用户的用户名:密码sudo
也就是说,在一个真实的例子中,你的脚本在内存中根本不应该有明文密码;相反,它应该在
/etc/sudoers
中配置为具有无密码权限升级。sudo
不从stdin读取密码——它也不应该读取密码,因为您的echo passd23
天生就不安全……因此,该行为正确地阻止了您执行这种极度不安全的操作,这将向系统上可以读取进程表的每个程序公开您的密码。(说到极度不安全——密码可以包含文字引号,因此尝试使用文字引号在直接替换到shell命令行的代码中转义shell密码是鲁莽的。如果新用户在此GUI中将其密码指定为'$(rm-rf/*),
——使命令sudo'username':''$(rm rf/*)“
,在硬编码代码中打开的引号在密码本身中关闭,你会有非常非常糟糕的一天。”@Charles Duffy我没有在这里写下真正的密码,是我编造的,但我写的更像是我代码的一个例子,这里的任何信息都不应该被认真对待:)这一切都是为了大学,不适用于公司它没有在StackOverflow中发布,这使得它不安全。它被发布在操作系统的进程列表中(系统上的每个用户都可以读取,包括nobody
——用于未经验证和不可信代码的帐户),这使得密码不安全。决不能在命令行上传递密码。