Python 结构差异sudo()运行(';sudo cmd';)

Python 结构差异sudo()运行(';sudo cmd';),python,sudo,fabric,Python,Sudo,Fabric,我想知道函数sudo()和函数run('sudo-u user smth') 文件上有: sudo在运行的各个方面都是相同的,只是它总是包装 调用sudo程序以提供超级用户的给定命令 特权 但是有几次,sudo('cmd')会提示我一个密码,但是如果我用run('sudo cmd')切换,它就不会提示我任何东西。这两者之间有什么变化吗?(我记得有人这么说,sudo和run(sudo cmd)不是同一个用途,但我找不到了)我发现了这两个不同之处 1: 2: 首先,当使用sudo()时,fabric

我想知道函数
sudo()
和函数
run('sudo-u user smth')

文件上有:

sudo在运行的各个方面都是相同的,只是它总是包装 调用sudo程序以提供超级用户的给定命令 特权


但是有几次,
sudo('cmd')
会提示我一个密码,但是如果我用
run('sudo cmd')
切换,它就不会提示我任何东西。这两者之间有什么变化吗?(我记得有人这么说,
sudo
run(sudo cmd)
不是同一个用途,但我找不到了)

我发现了这两个不同之处

1:

2:

首先,当使用sudo()时,fabric将从缓存中获取密码,然后您不需要输入密码。但如果使用run('sudo cmd'),则需要为每个'sudo cmd'输入密码

第二,如果您不想在root用户组下执行命令,而想在其他用户组(如www)下执行命令,只需设置env.sudo_user='www'或sudo('cmd',user='www')。第一个命令将在www下执行每个sudo(),第二个命令将在www下执行单个cmd。但是在使用run()命令时,您需要编辑以运行(“sudo-u'www'cmd”)


从Fabric 2开始,您可以通过
run()
调用
sudo
,这将提示输入密码,除非您使用自动响应程序。请注意,
sudo
命令通常远程缓存密码,因此在同一连接期间下次调用
sudo
时不会提示输入密码

但是,Fabric
sudo()
helper使使用
sudo
更加容易。您需要确保填写了
sudo.password
配置值(通过配置对象、配置文件、环境变量或
--提示输入sudo密码
)。以下是我如何使用该模块:

from fabric.api import sudo, run, env

env.hosts = ['host_ip',]
env.user = 'user_name'
env.sudo_user = 'sudo_user'


def test_1():
    run('sudo pwd')

def test_2():
    sudo('pwd')



$ fab -I --show=debug test_1 test_2
Initial value for env.password:   # enter password
Commands to run: test_1, test_2
Parallel tasks now using pool size of 1
[ip_address] Executing task 'test_1'
[ip_address] run: /bin/bash -l -c "sudo pwd"
[ip_address] out: [sudo] password for billy:   # needs to enter password here
[ip_address] out: /home/billy
[ip_address] out: 

Parallel tasks now using pool size of 1
[ip_address] Executing task 'test_2'
[ip_address] sudo: sudo -S -p 'sudo password:'  -u "root"  /bin/bash -l -c  "pwd"
[ip_address] out: sudo password:  # only prompt, do not need enter password
[ip_address] out: /home/billy
[ip_address] out: 


Done.
Disconnecting from ip_address... done.
from fabric import task
import keyring

@task
def restart_apache(connection):
    # set the password with keyring.set_password('some-host', 'some-user', 'passwd')
    connection.config.sudo.password = keyring.get_password(connection.host, 'some-user')
    connection.sudo('service apache2 restart')