fabric difference sudo() run('sudo cmd')

那年仲夏 提交于 2019-12-22 08:10:45

问题


I'm wondering what is the difference between the function sudo() and the function run('sudo -u user smth')

On the doc there is :

sudo is identical in every way to run, except that it will always wrap the given command in a call to the sudo program to provide superuser privileges.

But a few time, sudo('cmd') prompt me a password, but if I switch with run('sudo cmd') it works without prompting me anything. Is there anything that change between the two ? (I remember someone on SO saying that sudo and run(sudo cmd) are not for the same use, but I can't find it back)


回答1:


I found these two difference.

1: Fabric maintains an in-memory password

2: sudo accepts additional user and group arguments

First, fabric would get password from cache when using sudo(), then you do not need to enter password. But if you use run('sudo cmd'), you need to enter password for each 'sudo cmd'.

Second, if you want to execute a command not under root but other user group like www, you just need to set env.sudo_user = 'www' or sudo('cmd', user='www'). The first would execute each sudo() under www, the second would execute this single cmd under www. But you need to edit to run("sudo -u 'www' cmd") when use run() command.

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.



回答2:


Since Fabric 2, you can invoke sudo via run(), which will prompt for the password unless you use the auto-responder, details here. Note that the sudo command usually caches the password remotely, so next invocations of sudo during the same connection will not prompt for password.

However, the Fabric sudo() helper makes using sudo much easier, details here. You need to ensure that the sudo.password configuration value is filled in (via config object, config file, environment variable, or --prompt-for-sudo-password). Here's how I do it with the keyring module:

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')


来源:https://stackoverflow.com/questions/38345184/fabric-difference-sudo-runsudo-cmd

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!