linux中使用expect完成自动化登陆等操作非常方便,但是python调用linux执行expect的相关指导非常少。
下面写了一个python调用expect脚本完成主机向其他不同主机间拷贝和自动化免密码ssh登陆的实现。
#!/usr/bin/python
#coding:utf-8
import sys,re
import os
import subprocess
#scp file to remote node.
def scpFileToRemoteNode(user,ip,password,fileName,filePath,port=22):
'''
拷贝软件包到远程节点,默认使用root用户22号端口传输
:param ip:
:param password:
:param sourceFileName:
:return: 0 表示执行成功
'''
SCP_CMD_BASE = r"""
expect -c "
set timeout 10 ;
spawn scp -P {port} {filePath}/{{filename}} {username}@{host}:{filePath}/{{filename}} ;
expect *assword* {{{{ send {password}\r }}}} ;
expect *\r ;
expect \r ;
expect eof
"
""".format(username=user,password=password,host=ip,filePath=filePath,port=port)
SCP_CMD = SCP_CMD_BASE.format(filename = fileName)
print "execute SCP_CMD: ",SCP_CMD
p = subprocess.Popen( SCP_CMD , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
#status = os.system(SCP_CMD)
print "execute SCP_CMD status: ",output
return output
#ssh connect node ,then execute shell commands.
def sshCommandExecute(user,ip,password,command):
'''
使用ssh命令连接远程服务虚拟机,然后执行command命令,默认使用root用户
:param user:默认使用root用户
:param ip:
:param paasword:
:param command:
:return:
'''
SSH_CMD=r"""
expect -c "
set timeout 10;
spawn ssh {user}@{ip} ;
expect {{
\"*yes/no*\" {{ send "yes\r"; exp_continue }}
\"*assword*\" {{ send {password}\r }}
}} ;
send \" {command} \r\";
expect "]*"
send \"exit\r\"
"
""".format(user=user,ip=ip,password=password,command=command)
print "execute SSH_CMD: ",SSH_CMD
#status = os.system(SSH_CMD)
p = subprocess.Popen( SSH_CMD , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
print "execute SSH_CMD status: ",output
return output
有相关需求的可以直接拿去用。 expect 语句是放在python原始字符串中传递的,脚本在原始字符串中涉及到语句转义和参数传递。 每一次send语句执行最好使用expect上一条指令已经执行完成。