使用expect自动化脚本Telnet远端登陆device端,在同一个session中发送多条命令顺序执行,结束后返回命令集在终端执行所产生的log,交给Python处理。
- expect 中 if 使用
- expect 正则使用
- tcprelay + telnet
- python 调用 expect
- 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"
......
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))
- 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
'''
if timeout < 0 and timeout != -1:
writeLogs("Timeout setting value illegal")
exit(255)
import time,signal
rev = []
p = subprocess.Popen( args, shell=isShell, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
if timeout<=0:
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)
writeLogs_EXP(buff)
else:
try:
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout)
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)
writeLogs_EXP(buff)
signal.alarm(0)
except AssertionError:
writeLogs_EXP("CMDError: '%s' timeout" %(args[0]))
#print("rev=",rev)
return (False, rev)
if p.wait() == 0: ## get cmd result value
res = True
else:
res = False
return (res, rev) ## res(Bool): The cmd is running successful?
## rev(String): The cmd result string.
- Python调用执行:
getOSLogs( "/dev/cu.serial2", ['ls', 'pwd'])
这里只是匆忙记录一下,有空再详细介绍。
参考:
1>. Expect 手册中文版 https://blog.51cto.com/lielie/1537942 (转载)
tips:更详细的expect介绍请直接查看man expect