远程执行多个shell命令,包括" df -h"在python中使用root用户

时间:2017-05-23 13:02:40

标签: python shell

我想做以下事情:

    if condition:
            cmd="ssh machine1 && sudo su - && df -h PathThatRequiresRootPriv | grep ..."

    proc = subprocess.Popen(cmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,env=os.environ)
    (out_space,err) = proc.communicate()
    if err: 
            print err
            log.warning('%s',err)
            exit(1)

但我显然遗漏了一些东西,因为该计划并没有做任何事情。 感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

您正在以function or(a, b) { return !(!a && !b) } 的形式构建命令。 3个命令在本地计算机上一次执行一个,除非其中一个返回false。从你的标题来看,它不是你所期望的......而且构造cmd1 && cmd2 && cmd3的行为是相同的,并且期望它的命令来自它自己的标准输入,而不是来自下一个命令。

这里的正确方法是:

sudo su -

换句话说,您应该只在本地计算机上执行if condition: loc_cmd="ssh machine1" remcmd="sudo -i 'df -h PathThatRequiresRootPriv | grep ...'" proc = subprocess.Popen(loc_cmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,env=os.environ) (out_space,err) = proc.communicate(rem_cmd) ,将ssh传递给远程,作为在模拟初始登录后执行命令的请求,最后将管道作为参数传递到sudo -i

答案 1 :(得分:0)

你必须看fabric - 如果你想使用python 或ansible

在结构中,您可以在远程服务器上执行不同的操作,如下所示:

from fabric.api import *

def check_disk_space(username, passw='none'):
    host = '%s@%s' % (env.user, env.host)
    env.passwords[host] = 'rootPass'
    # run from user
    run('df -h')
    # run from sudo
    sudo('df -h')

host='anyuser@10.10.10.101'
execute(check_disk_space, hosts=[host], username='anyuser', passw='')

支持'成为'通过sudo执行远程命令的方法

答案 2 :(得分:0)

很抱歉这么晚才回复你,但我必须完成这个程序的另一部分,所以我可以测试它作为一个整体。

这里是我的代码(它只返回可用磁盘空间的百分比):

loc_cmd="ssh ccage"
            remcmd="sudo -i 'df -h "+str_home_dir+" | awk 'FNR==2 {print $5}' | tr -d '%'' "
            proc = subprocess.Popen(loc_cmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,env=os.environ)
           (out_space,err) = proc.communicate(rem_cmd)

以及我收到的错误消息:

NameError: global name 'rem_cmd' is not defined
Pseudo-terminal will not be allocated because stdin is not a terminal.

所以我尝试使用sudo bash -c而不是sudo -i并获得以下消息:

(out_space,err) = proc.communicate(rem_cmd) 
NameError: global name 'rem_cmd' is not defined
Pseudo-terminal will not be allocated because stdin is not a terminal.

我不明白为什么我会收到这些错误,因为当我直接在机器上执行时,以下行可以正常运行" ccage":

sudo -i 'df -h "+str_home_dir+" | awk 'FNR==2 {print $5}' | tr -d '%''