在脚本中使用ssh(w / expect或paramiko)不能按预期工作

时间:2016-06-26 08:25:12

标签: python ssh redhat paramiko

我是Python的新手

我想使用Python编写SSH脚本来重启机器 这是我的功能:

def sendCommandViaSSH(usr,psswrd,command):
    line = 'ssh '+ usr +'@'+ RIp + ' ' +"\""+ command+"\""
    print_message(line)
    child = pexpect.spawn (line)
    #i = child.expect('Are you sure you want to continue connecting (yes/no)?')
    i = child.expect (['Are you sure you want to continue connecting (yes/no)?', pexpect.EOF, pexpect.TIMEOUT],2)
    print_message(i)
    if i == 0:
        child.sendline ('yes')
    i = child.expect(['s password:', pexpect.EOF, pexpect.TIMEOUT])
    print_message(i)
    if i == 0:
        print_message(psswrd)
        child.sendline (psswrd)

我的问题是不起作用 如果我手动运行相同的命令一切正常

示例输出:

ssh MyUsr@XXX.XXX.XXX.XXX "shutdown -k now"
2
0
MyPsswrd

如果我只是从输出中复制/粘贴它可以正常工作 我的机器和我的遥控器都是RedHat6.4 它没有任何我知道的安全性变化

问题是什么或以其他方式可以做到这一点?

修改 阅读完评论后我已经移动(返回)使用paramiko_1.17.1 module 但......问题仍然存在

下面:

1.code that i wrote so far
2.output that I get using it (while encountering the same problem of not working commands )

这是我的新代码:

import paramiko
import logging
logging.basicConfig(level=logging.DEBUG)

def exec_paramiko(ssh, command):
    print_message("executing '{0}' on remote machine".format(command))
    chan = ssh.get_transport().open_session()
    chan.get_pty()
    f = chan.makefile()
    chan.exec_command(command)
    flag=True
    exit_code=None
    output=""
    while True:
        if chan.recv_ready():
            output+=(chan.recv(4096).decode('ascii') + "\n")
        if chan.recv_stderr_ready():
            output+=("error: {0}".format(chan.recv_stderr(4096).decode('ascii')))
        if chan.exit_status_ready():
            output+=(chan.recv(4096).decode('ascii') + "\n")
            error_string=0
            if chan.recv_stderr_ready():
                error_string=chan.recv_stderr(4096).decode('ascii')
            exit_code = chan.recv_exit_status()
            if exit_code != 0:
                output+="\nerror: {0}".format(error_string)
            break
    return exit_code, output

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname="10.xx.xx.xx",username="usr",password="psswrd",allow_agent=False,look_for_keys=False, timeout=20)
exit_code, output = exec_paramiko(ssh,'shutdown -k now' )
print "error code: {0} message: {1}".format(exit_code, output)

输出

DEBUG:paramiko.transport:starting thread (client mode): 0xdb17c310L
DEBUG:paramiko.transport:Local version/idstring: SSH-2.0-paramiko_1.17.1
DEBUG:paramiko.transport:Remote version/idstring: SSH-2.0-OpenSSH_5.3
INFO:paramiko.transport:Connected (version 2.0, client OpenSSH_5.3)
DEBUG:paramiko.transport:kex algos:[u'diffie-hellman-group-exchange-sha256', u'diffie-hellman-group-exchange-sha1', u'diffie-hellman-group14-sha1', u'diffie-hellman-group1-sha1'] server key:[u'ssh-rsa', u'ssh-dss'] client encrypt:[u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'arcfour256', u'arcfour128', u'aes128-cbc', u'3des-cbc', u'blowfish-cbc', u'cast128-cbc', u'aes192-cbc', u'aes256-cbc', u'arcfour', u'rijndael-cbc@lysator.liu.se'] server encrypt:[u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'arcfour256', u'arcfour128', u'aes128-cbc', u'3des-cbc', u'blowfish-cbc', u'cast128-cbc', u'aes192-cbc', u'aes256-cbc', u'arcfour', u'rijndael-cbc@lysator.liu.se'] client mac:[u'hmac-md5', u'hmac-sha1', u'umac-64@openssh.com', u'hmac-ripemd160', u'hmac-ripemd160@openssh.com', u'hmac-sha1-96', u'hmac-md5-96'] server mac:[u'hmac-md5', u'hmac-sha1', u'umac-64@openssh.com', u'hmac-ripemd160', u'hmac-ripemd160@openssh.com', u'hmac-sha1-96', u'hmac-md5-96'] client compress:[u'none', u'zlib@openssh.com'] server compress:[u'none', u'zlib@openssh.com'] client lang:[u''] server lang:[u''] kex follows?False
DEBUG:paramiko.transport:Kex agreed: diffie-hellman-group1-sha1
DEBUG:paramiko.transport:Cipher agreed: aes128-ctr
DEBUG:paramiko.transport:MAC agreed: hmac-md5
DEBUG:paramiko.transport:Compression agreed: none
DEBUG:paramiko.transport:kex engine KexGroup1 specified hash_algo <built-in function openssl_sha1>
DEBUG:paramiko.transport:Switch to new keys ...
DEBUG:paramiko.transport:Adding ssh-rsa host key for xx.xx.xx.xx: 0c13035c7e4c0e3999d1c85215e97394
DEBUG:paramiko.transport:userauth is OK
INFO:paramiko.transport:Authentication (password) successful!
DEBUG:paramiko.transport:[chan 0] Max packet in: 32768 bytes
DEBUG:paramiko.transport:[chan 0] Max packet out: 32768 bytes
DEBUG:paramiko.transport:Secsh channel 0 opened.
DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok
INFO:paramiko.transport.sftp:[chan 0] Opened sftp connection (server version 3)
shutting down
executing 'shutdown -k now' on remote machine
DEBUG:paramiko.transport:[chan 1] Max packet in: 32768 bytes
DEBUG:paramiko.transport:[chan 1] Max packet out: 32768 bytes
DEBUG:paramiko.transport:Secsh channel 1 opened.
DEBUG:paramiko.transport:[chan 1] Sesch channel 1 request ok
DEBUG:paramiko.transport:[chan 1] Sesch channel 1 request ok
DEBUG:paramiko.transport:[chan 1] EOF received (1)
DEBUG:paramiko.transport:[chan 1] EOF sent (1)
error code: 0 message: 

DEBUG:paramiko.transport:EOF in transport thread

2 个答案:

答案 0 :(得分:0)

这有sshpass,但我总是使用公钥。但是如果公钥是你无法做到的,那么在Python中进行子处理:

sshpass -pfoobar ssh -o StrictHostKeyChecking=no user@host command_to_run

这是工具网址:https://sourceforge.net/projects/sshpass/

答案 1 :(得分:0)

经过多次搜索和阅读后,我发现了一些有用的东西

我的问题的原因是未知(如果我发现与版本相关或某些通用的内容,我会尝试更新)

原始代码:

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.exec_command(command)

修改后的代码:

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())    
chan = ssh.get_transport().open_session()
#instead of ssh.exec_command(command)
chan.exec_command(command)

如果有人可以花费我为什么工作,我想知道:)