在一些场景下服务器不允许直接使用root用户来登陆,而是需要登陆admin账户或者其他账户后,譬如说公司的ap就是这样子的

再进行切换进入到root用户,这是后中间就涉及到了密码的输入问题,如之前的Paramiko文章中是无法进行root用户的切换的

之前一直没有解决,主要是不需要用到root用户,正巧现在在写一个相关的脚本时,一定需要使用到root,那么一定需要解决的

感觉实现的方式有那么一点类似之前自动部署server脚本中的expect,其原理也是通过ssh回显的字符串来判断输入值,当看到Password:时

使用ssh.send()方法发送字符串及回车来确认,使用这样的形式可以模拟一个交互式的shell,ssh会记住上一次执行的是什么,下一次会接着进行

譬如说:第一条命令为cd /home,第二条为ls,那么查看的是home下的文件,而之前的方式,只会执行ls,相当于默认查看了root文件夹下面的文件

chan = ssh.invoke_shell() #在SSH server端创建一个交互式的shell,且可以按自己的需求配置伪终端,可以在invoke_shell()函数中添加参数配置。

chan.send(cmd+’\n’) #利用send函数发送cmd到SSH server,添加’\n’做回车来执行shell命令。注意不同的情况,如果执行完telnet命令后,telnet的换行符是\r\n

chan.recv(bufsize) #通过recv函数获取回显

重点是,有些命令执行的时间长,不适当的receive回来可能得不到想要的结果,可以使用time.sleep()进行等待,或使用一些条件循环

但是时间不好去把握,有的长有的短,所以使用判断的方法来实现更加智能,也就是start_cmd函数

def start_cmd(ssh,cmd):
    cmd = cmd+' \n'
    ssh.send(cmd)
    buff = ''
    while not buff.endswith('# '):
        time.sleep(0.1)
        resp = ssh.recv(9999)
        buff +=resp

将buff设置为空字符,当回显的值最后是’# ‘就跳出循环了,若不是则说明命令还没有结束再次判断,直到的到最后的字符串为# ,是#空格,不是单单一个#号,这个具体看终端返回的最后是什么

使用buff.endswith(‘# ‘)这个方法来判断,这个方法是指在buff的字符串中结尾是不是‘# ’结尾,若是是的返回true,否则false实现一个交互式的shell

#coding:utf-8
import paramiko,time

def start_cmd(ssh,cmd):
    cmd = cmd+' \n'
    ssh.send(cmd)
    buff = ''
    while not buff.endswith('# '):
        time.sleep(0.1)
        resp = ssh.recv(9999)
        buff +=resp
    print(resp)

def input_cmd(ssh):
    buff = ''
    while not buff.endswith('# '):
        cmd = raw_input()
        if cmd == 'exit':
            break
        start_cmd(ssh,cmd)

def verification_ssh(host,username,password,port,root_pwd):
    s=paramiko.SSHClient()
    s.load_system_host_keys()
    s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    s.connect(hostname = host,port=int(port),username=username, password=password)
    ssh = s.invoke_shell()
    time.sleep(0.1)
    if username != 'root':
        ssh.send('su \n')
        buff = ''
        while not buff.endswith('Password: '):
            time.sleep(0.1)
            resp = ssh.recv(9999)
            buff +=resp
        print(buff)
        ssh.send(root_pwd)
        ssh.send('\n')
        time.sleep(1)
        print(buff)
        input_cmd(ssh)
    else:
        input_cmd(ssh)
    s.close()

if __name__ == '__main__':
    verification_ssh('192.168.16.113','zw','12345678','22','zhushisheng')

 

写的一个调整ap-txpower的脚本,与之前的脚本相似,稍微一点改动

#coding:utf-8
import paramiko,time

def start_cmd(ssh,cmd):
    cmd = cmd+' \n'
    ssh.send(cmd)
    buff = ''
    while not buff.endswith('# '):
        time.sleep(0.1)
        resp = ssh.recv(9999)
        buff +=resp

def verification_ssh(host,username,password,port,root_pwd):
    s=paramiko.SSHClient()
    s.load_system_host_keys()
    s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    s.connect(hostname = host,port=int(port),username=username, password=password)
    ssh = s.invoke_shell()
    time.sleep(0.1)
    ssh.send('sudo /bin/ash \n')
    buff = ''
    while not buff.endswith('Password:'):
        time.sleep(0.1)
        resp = ssh.recv(9999)
        buff +=resp
    ssh.send(root_pwd)
    ssh.send('\n')
    time.sleep(1)
    print('- '*35)
    for i in xrange(25,2,-1):
        cmd = 'iwconfig ath000 txpower %s'%i
        start_cmd(ssh,cmd)
        print('Tx-power调整为:%s'%i)
        time.sleep(2)
    print('- '*35)
    s.close()



if __name__ == '__main__':
    verification_ssh('192.168.99.152','admin','admin','22','superwifi123')