我正在使用Fabric在远程服务器上运行命令.我在该服务器上连接的用户具有一些sudo权限,并且不需要密码即可使用这些权限.当SSH进入服务器时,我可以运行sudo blah
并执行命令而不提示输入密码.当我尝试通过Fabric的sudo
功能运行相同的命令时,系统会提示我输入密码.这是因为Fabric在使用时以下列方式构建命令sudo
:
sudo -S -p/bin/bash -l -c " "
显然,我的用户无权在/bin/bash
没有密码的情况下执行.
我通过使用run("sudo blah")
代替而解决了这个问题sudo("blah")
,但我想知道是否有更好的解决方案.这个问题有解决方法吗?
尝试传递shell=False
给sudo.那样/ bin/bash就不会被添加到sudo命令中. sudo('some_command', shell=False)
从fabric/operations.py的第503行:
if (not env.use_shell) or (not shell): real_command = "%s %s" % (sudo_prefix, _shell_escape(command))
else块看起来像这样:
# V-- here's where /bin/bash is added real_command = '%s %s "%s"' % (sudo_prefix, env.shell, _shell_escape(cwd + command))
您可以使用:
fabric.api import env # [...] env.password = 'yourpassword'
这是你问题最直接的答案:你实际上没有问题; 你误解了Fabric run()和sudo()是如何工作的.
您的"解决方法"不是解决方法,它是对问题的100%有效答案.
这是一组简单的规则:1)当你不期望提示时,使用"run()".2)当你期望提示时使用"sudo()".(对于需要提示的所有或大多数命令,这应该是正确的,即使有问题的可执行文件不是Bash或Sudo).
同样的答案适用于试图在"sudo"下运行命令的人.即使sudoers在某些系统上为当前用户配置了无密码配置,如果你使用sudo()而不是run(),那么你将强制提示(除非Fabric代码已经包含ENV密码或密钥).
BTW的作者在#IRC中回答了我的问题 - 与你的问题非常相似.好人,开源的无名英雄之一坚持他的Fabric和Paramiko工作.
...在我的测试环境中,总有一个用户名具有对sudo的完全无密码访问权限.打字sudo echo hello
不会提示我.此外,该sudo用户配置了"!requiretty",因此所有命令都可以通过SSH运行(如主机之间的SSH跳转).这意味着我可以简单地使用"run()"来执行"sudo something",但它只是另一个在没有提示的情况下运行的命令.就安全性而言,锁定生产主机而不是测试主机是某人的工作.(如果您被迫通过并且无法自动化测试,那么这是一个巨大的问题).
在你的/ etc/sudoers文件中添加
user ALL=NOPASSWD: some_command
其中user是你的sudo用户,some_command是你要用fabric运行的命令,然后在fabric脚本上运行sudo it with shell = False:
sudo('some_command', shell=False)
这对我有用