expect高级用法实例

10 篇文章 0 订阅
6 篇文章 0 订阅
  • 场景描述

使用expect自动化脚本Telnet远端登陆device端,在同一个session中发送多条命令顺序执行,结束后返回命令集在终端执行所产生的log,交给Python处理。

  • 示例技术

  1. expect 中 if 使用
  2. expect 正则使用
  3. tcprelay + telnet
  4. python 调用 expect
  • 源码

  1. auto_telnet.exp
#!/usr/bin/expect 
# ****************************************
# @Author: Cyril
# @Create: 19/02/23
# This is a auto script for exec telnet connection, Using it to replace 'scout remote'
# Usage: ./auto_telnet.rep <TelnetPort> <OSCMD_len>
# ****************************************

if {$argc<2 } {
        send_user "Error: Parameters incorrect \n"
        send_user "Usage: ./auto_telnet.rep <TelnetPort> <OSCMD_len> <OSCMD 1> <OSCMD 2> * * *\n"
        exit
}

set TelnetPort [lindex $argv 0]
set OSCMD_len [lindex $argv 1]

set param_num [expr {$argc-2}]
if { $OSCMD_len!=$param_num } {
	send_user "Parameters num incorrect \n"
	exit
}

## -1 means never timeout

set user "root"
set pwd "alpine"

set prompt "iPhone:~ root#"
#set prompt "gdlocal$ "

#send_tty命令用来实现在终端上显示提示符字串
#send_tty "$prompt"

set timeout 30
spawn telnet localhost $TelnetPort
exec sleep 1
expect { 
	-re "Are you sure you want to continue connecting (yes/no)?" { send "yes\r"; exp_continue }
	-re "login:" { send "$user\r"; exp_continue }
	-re "Password:" { send "$pwd\r" }
	eof { 
		send_error "Telnet conn disconnected. Exit.";
		exit 
	}
}

sleep 1

set index [expr {$argc - 1}]
for {set i 3} {$i <= $index} {incr i} {
	expect $prompt {	
		puts "index$i = [lindex $argv $i]"
		send "[lindex $argv $i] \r"
	} timeout 3 {
		send_user "Timeout...exit";
		exit
	} eof {
		send_error "EOF...finish";
		exit
	}
}

send_user "Finish"

  1. Tools.py
......
def getOSLogs(cableName, cLogsList):
	loc_id = getLocId(cableName)
	## init tcp_port value to 10000
	tcp_port = 10000
	## tcprelay process id (str)
	tcp_proc_id = ""

	try:
		## 1. Get eixsts tcprelay_ports list
		res, tcp_port_list = readCMD(["lsof -i tcp | grep tcprelay | awk -F ':' '{print $2}' | awk -F ' ' '{print $1}' | awk -F/ '!a[$1,$2]++'"], True)
		if res:
			## Produce a legal tcp_port for a new tcprelay connection.
			while (str(tcp_port+23) in tcp_port_list):
				tcp_port = tcp_port + 1
        
		## 2. Start tcprelay monitor.
		res, rev = readCMD(["tcprelay --locationid %s --portoffset %s 873 23 &" %(loc_id, tcp_port_list) ], True)
		#res, rev = readCMD(["/usr/local/bin/tcprelay --portoffset  '%d' '%d' '%d' &" %(tcp_port,  873, 23)], True, 1)
	        #    if res: ## 'res' is always False, should not be judged.
        
		## 3. Get Current tcprelay proc_id
		telnet_port = tcp_port + 23
		res, rev = readCMD( ["lsof -i tcp:%s | awk -F ' ' '{print $2}' | sed '/PID/d' | awk -F/ '!a[$1,$2]++'" %(telnet_port)], True)
		tcp_proc_id = rev[0]
		writeLogs("Current tcprelay process_id = %s" %tcp_proc_id)
        
        
		## 4. Open telnet connection
		telnet_cmd = script_path + "/auto_telnet.exp %s %s" %( str(telnet_port), str(cLogsList.count))
	#	for i in cLogsList.count:
	#		telnet_cmd = telnet_cmd + " " + str(cLogsList[i])
		writeLogs("DEBUG 63: telnet_cmd = %s" %telnet_cmd)
		#telnet_cmd = script_path + "/auto_telnet.exp ls pwd"
		#res, telnet_rev = readCMD( [script_path+"/auto_telnet.exp %s %s" %(str(tcp_port + 23), str(cLogsList.count)) ], True)
		telnet_rev_list = []
	        #	cLogsList.append("exit")
        	for item in cLogsList:
			telnet_cmd = telnet_cmd + ' "%s" "%s" ' %( telnet_port, item)
			res, rev = readCMD( [telnet_cmd ], True)
			telnet_rev_list.append(rev)
#			#yield telnet_rev_list
		        if "Connection closed by foreign host." in rev and "Connection closed by foreign host." not in rev[-1]:
				writeLogs("Telnet port-%s open failed, OS cmd executed failed." %(telnet_port) )
				kill_tcprelay(tcp_proc_id)
				print("rev=None")
	except Exception as e:
        	writeLogs(e)
	        # Kill Tcprelay conn
        	kill_tcprelay(tcp_proc_id)
		print("rev=None")
		return list_to_str(telnet_rev_list)
	else:
		# Kill Tcprelay conn
		kill_tcprelay(tcp_proc_id)
		print("rev=%s" %list_to_str(telnet_rev_list))

  1. Python 执行Shell命令函数
def readCMD(args=[], isShell=True, timeout=-1):
        '''
        #Running the command and read String from stdout.
        #@param args(list): cmd script path & cmd params
        #@param isShell(Bool): The cmd is shell cmd or not.
        #@param timeout(int): set timeout(must > 0), default -1 means never timeout
        #@return (res, rev): res: result status code
        #                   rev: result string
        '''
        import subprocess
        from subprocess import Popen

        if timeout < 0 and timeout != -1:
                print("Timeout setting value illegal")
                exit(255)
        res = False
        rev = []
        p = subprocess.Popen( args, shell=isShell, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

        while True:
            buff = p.stdout.readline().strip().replace("\r\n", "")
            if p.poll() != None:
                if buff == '':
                    break;
            if buff != '':
                buff.strip().replace("\n", "")
                rev.append(buff)
                print(buff)

            if p.wait() == 0:
                res = True
                break

        return (res, rev)         ## res(Bool): The cmd is running successful?
                                ## rev(String): The cmd result string.
  1. Python调用执行:
getOSLogs( "/dev/cu.serial2",  ['ls', 'pwd'])

这里只是匆忙记录一下,有空再详细介绍。

参考:

1>. Expect 手册中文版 https://blog.51cto.com/lielie/1537942 (转载)

tips:更详细的expect介绍请直接查看man expect

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值