如何以系统用户身份运行bash命令,而不给予该用户以任何用户

时间:2017-01-26 09:47:34

标签: python bash ssh visudo

我编写了一个包含以下行的python脚本:

response = subprocess.check_output(['/usr/bin/sudo /bin/su - backup -c "/usr/bin/ssh -q -o StrictHostKeyChecking=no %s bash -s" <<\'EOF\'\nPATH=/usr/local/bin:$PATH\nmvn --version|grep -i Apache|awk \'{print $3}\'|tr -d \'\n\'\nEOF' % i], shell=True)

这是一个for循环,它遍历一个主机名列表,每个我想检查一下命令的结果。当我自己运行它时这很好用,但是,这个脚本是由系统用户运行的(shinken - 一个nagios fork),那时我遇到了一个问题。

shinken ALL=(ALL) NOPASSWD: ALL

但是,我想限制用户只允许它作为备份用户运行:

shinken ALL=(backup) NOPASSWD: ALL

但是当我运行脚本时,我得到了:

sudo: no tty present and no askpass program specified

我已经阅读了这篇文章并尝试了一些方法来解决它。我尝试在我的ssh命令中添加-t,但这没有帮助。我相信我应该可以使用类似的命令运行命令:

response = subprocess.check_output(['/usr/bin/sudo -u backup """ "/usr/bin/ssh -q -o StrictHostKeyChecking=no %s bash -s" <<\'EOF\'\nPATH=/usr/local/bin:$PATH\njava -version|grep -i version|awk \'{print $3}\'|tr -d \'\n\'\nEOF""" ' % i], shell=True)

但后来我得到了这个答复:

subprocess.CalledProcessError: Command '['/usr/bin/sudo -u backup """ "/usr/bin/ssh -q -o StrictHostKeyChecking=no bamboo-agent-01 bash -s" <<\'EOF\'\nPATH=/usr/local/bin:$PATH\njava -version|grep -i version|awk \'{print $3}\'|tr -d \'\n\'\nEOF""" ']' returned non-zero exit status 1

如果我手动运行命令,我会得到:

sudo:  /usr/bin/ssh: command not found

这很奇怪,因为它就在那里......我不知道我正在尝试的是否可能。谢谢你的任何建议!

1 个答案:

答案 0 :(得分:2)

至于sudo

shinken ALL=(backup) NOPASSWD: ALL

...仅在您将直接shinken切换为backup时才有效。 你不是在这里做的sudo su - backup告诉sudo切换为root ,并以root身份运行命令su - backup 。显然,如果你打算使用sudo su(我在其他地方提出建议),你需要/etc/sudoers配置来支持它。

由于您的/etc/sudoers不允许直接切换到您要求的root,因此它会尝试提示输入密码,这需要TTY,从而导致失败。

下面,我正在重写脚本,以便直接从shinken切换到backup,而不用通过root并运行su

至于剧本:

import subprocess

remote_script='''
PATH=/usr/local/bin:$PATH
mvn --version 2>&1 | awk '/Apache/ { print $3 }' 
'''

def maven_version_for_host(hostname):

    # storing the command lets us pass it when constructing a CalledProcessError later
    # could move it directly into the Popen creation if you don't need that.
    cmd = [
        'sudo', '-u', 'backup', '-i', '--',
        'ssh', '-q', '-o', 'StrictHostKeyChecking=no', str(hostname),
        'bash -s' # arguments in remote-command position to ssh all get concatenated
                  # together, so passing them as one command aids clarity.
    ]
    proc = subprocess.Popen(cmd,
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    response, error_string = proc.communicate(remote_script)
    if proc.returncode != 0:
        raise subprocess.CalledProcessError(proc.returncode, cmd, error_string)
    return response.split('\n', 1)[0]