Python脚本编程与系统管理

发布于 2017-10-06 · 本文总共 4474 字 · 阅读大约需要 13 分钟

示例1:

  • ftp自动登录下载

import pexpect
ipAddress = 'develperWorks.ibm.com'
loginName = 'root'
loginPassword = 'passw0rd'

cmd = 'ftp ' + ipAddress

child = pexpect.spawn(cmd)

index = child.expect(["(?i)name", "(?i)Unknown host", pexpect.EOF, pexpect.TIMEOUT])
if ( index == 0 ):
    child.sendline(loginName)
    index = child.expect(["(?i)password", pexpect.EOF, pexpect.TIMEOUT])
    if (index != 0):
        print "ftp login failed"
        child.close(force=True)
    child.sendline(loginPassword)
    index = child.expect( ['ftp>', 'Login incorrect', 'Service not available',
    pexpect.EOF, pexpect.TIMEOUT])

    if (index == 0):
        print 'Congratulations! ftp login correct!'
        # 发送 'bin'+ 换行符给子程序,表示接下来使用二进制模式来传输文件.
        child.sendline("bin")
        print 'getting a file...'
        # 向子程序发送下载文件 rmall 的命令.
        child.sendline("get rmall")
        # 期望下载成功后,出现 'Transfer complete.*ftp>',其实下载成功后,
        # 会出现以下类似于以下的提示信息:
        #    200 PORT command successful.
        #    150 Opening data connection for rmall (548 bytes).
        #    226 Transfer complete.
        #    548 bytes received in 0.00019 seconds (2.8e+03 Kbytes/s)
        # 所以直接用正则表达式 '.*' 将 'Transfer complete' 和提示符 'ftp>' 之间的字符全省去.
        index = child.expect( ['Transfer complete.*ftp>', pexpect.EOF, pexpect.TIMEOUT] )
        # 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.
        if (index != 0):
            print "failed to get the file"
            child.close(force=True)
        # 匹配到了 'Transfer complete.*ftp>',表明下载文件成功,打印成功信息,并输入 'bye',结束 ftp session.
        print 'successfully received the file'
        child.sendline("bye")
    # 用户名或密码不对,会先出现 'Login incorrect',然后仍会出现 'ftp>',但是 pexpect 是最小匹配,不是贪婪匹配,
    # 所以如果用户名或密码不对,会匹配到 'Login incorrect',而不是 'ftp>',然后程序打印提示信息并退出.
    elif (index == 1):
        print "You entered an invalid login name or password. Program quits!"
        child.close(force=True)
    # 匹配到了 'Service not available',一般表明 421 Service not available, remote server has
    # closed connection,程序打印提示信息并退出.
    # 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.
    else:
        print "ftp login failed! index = " + index
        child.close(force=True)
# 匹配到了 "(?i)Unknown host",表示 server 地址不对,程序打印提示信息并退出
elif index == 1 :
    print "ftp login failed, due to unknown host"
    child.close(force=True)
# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出
else:
    print "ftp login failed, due to TIMEOUT or EOF"
    child.close(force=True)

示例2:

  • 记录log
import pexpect
p = pexpect.spawn(  ls -l  )
fout = open ('log.txt', "w")
p.logfile = fout
p.expect(pexpect.EOF)
fout.close()

示例3

  • ssh登录 通过SSH运行远程shell命令: 命令格式: ssh -l name remoteserver ‘command’

import pexpect
import getpass, os

def ssh_command (user, host, password, command):
    ssh_newkey = 'Are you sure you want to continue connecting'
    # 为 ssh 命令生成一个 spawn 类的子程序对象.
    child = pexpect.spawn('ssh -l %s %s %s'%(user, host, command))
    i = child.expect([pexpect.TIMEOUT, ssh_newkey, 'password: '])
    if i == 0: # Timeout
        print 'ERROR!'
        print 'SSH could not login. Here is what SSH said:'
        print child.before, child.after
        return None
    # 如果 ssh 没有 public key,接受它.
    if i == 1: # SSH does not have the public key. Just accept it.
        child.sendline ('yes')
        child.expect ('password: ')
        i = child.expect([pexpect.TIMEOUT, 'password: '])
        if i == 0: # Timeout
        print 'ERROR!'
        print 'SSH could not login. Here is what SSH said:'
        print child.before, child.after
        return None
    # 输入密码.
    child.sendline(password)
    return child

def main ():
    host = raw_input('Hostname: ')
    user = raw_input('User: ')
    #getpass.getpass() 来获得用户输入的密码,与 raw_input 不同的是,getpass.getpass() 不会将用户输入的密码字符串 echo 回显到 stdout 上。
    password = getpass.getpass()
    command = raw_input('Enter the command: ')
    child = ssh_command (user, host, password, command)
    # 匹配 pexpect.EOF
    child.expect(pexpect.EOF)
    print child.before

if __name__ == '__main__':
    try:
        main()
    except Exception, e:
        print str(e)
        traceback.print_exc()
        os._exit(1)

shell脚本实现

  • ssh -t -p $port $user@$ip ‘cmd’

可以提供一个远程服务器的虚拟tty终端,加上这个参数我们就可以在远程服务器的虚拟终端上输入自己的提权密码了,非常安全 -t虚拟出一个远程服务器的终端,在多台服务器同时部署时


ip_array=("192.168.1.1" "192.168.1.2" "192.168.1.3")
user="paas"
remote_cmd="/home/test/1.sh"

#本地通过ssh执行远程服务器的脚本
for ip in ${ip_array[*]}
do
	if [ $ip = "192.168.1.1" ]; then
		port="7777"
	else
		port="22"
	fi
	ssh -t -p $port $user@$ip "remote_cmd"
done

示例:

import sys
import pexpect

password = 'password'
expect_list = ['(yes/no)', 'password:']

p = pexpect.spawn('ssh username@localhost ls')
try:
    while True:
        idx = p.expect(expect_list)
        print p.before + expect_list[idx],
        if idx == 0:
            print "yes"
            p.sendline('yes')
        elif idx == 1:
            print password
            p.sendline(password)
except pexpect.TIMEOUT:
    print >>sys.stderr, 'timeout'
except pexpect.EOF:
    print p.before
    print >>sys.stderr, '<the end>'

Python-paramiko

示例1:

  • ftp自动登录下载
import paramiko
def ssh2(ip='162.3.210.32',username='root',passwd='huawei',commands=[]):
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(ip, 22, username, password=passwd, timeout=4)
    for cmd in commands:
        print cmd
        stdin, stdout, stderr = client.exec_command(cmd)
        for std in stdout.readlines():
          print std,
    print "%s\tOK\n"%ip
    client.close()

参考资料

http://blog.csdn.net/songfreeman/article/details/50920767

https://www.ibm.com/developerworks/cn/linux/l-cn-pexpect2/index.html




本博客所有文章采用的授权方式为 自由转载-非商用-非衍生-保持署名 ,转载请务必注明出处,谢谢。
声明:
本博客欢迎转发,但请保留原作者信息!
博客地址:邱文奇(qiuwenqi)的博客;
内容系本人学习、研究和总结,如有雷同,实属荣幸!
阅读次数:

文章评论

comments powered by Disqus


章节列表