Design Intent: Initialize the Spawn object once, execute SSH post, a series of Cmds. Most of the time online via SSH [email protected] cmd method, so that I need to call through for:
def ssh_commands (ip,user,passwd,command): try:ssh_pc = Pexpect.spawn (' SSH%[email protected]%s%s '% (user,ip,c Ommand), Timeout=5,logfile=logfile) ... r=ssh_pc.read () print R except TIMEOUT,EOF:SSH_PC.C Lose () ... for cmd in Cmds:ssh_commands (ip,user,passwd,cmd)
However, the Spawn object is generated for each for, so my method is:
def ssh_commands (ip,user,passwd,commands): try:ssh_pc = Pexpect.spawn (' SSH%[email protected]%s '% (user,ip), TI meout=5,logfile=logfile) ... for command in Commands:ssh_pc.expect (' # ') Ssh_pc.sendli NE (command) r=ssh_pc.read () print R except Timeout,eof:ssh_pc.close () ... Ssh_commands (IP,USER,PASSWD,CMDS)
My code is as follows:
Import pexpectimport sysdef ssh_commands (ip,user,passwd,commands): ip= STR (IP) user=str (user) passwd=str (passwd) #logfile =file ('%s_%s ' % (ip,user), ' W ') logfile=sys.stdout ssh_pc = pexpect.spawn (' ssh %[email protected]%s ' % (USER,IP), Timeout=5,logfile=logfile) try: match_tag = ssh_pc.expect ([' continue connecting (yes/no)? ', ' Password: '],timeout=3 ' if match_tag==0: print ' # ' *30 ssh_pc.sendline (' yes ') ssh_pc.expect (' Password: ') ssh_pc.sendline (PASSWD) elif match_tag==1: print ' = ' *30 ssh_pc.sendline (passwd) for cmd in commands: ssh_pc.expect ([' # ', Pexpect. Timeout,pexpect. EOF]) ssh_pc.sendline (cmd) ssh_pc.expect ([' # ', Pexpect. Timeout,pexpect. EOF]) ssh_pc.close #ssh_pc. Sendline (' exit ') print ssh_pc.read () except pexpect. eof: print ' sub process abort Unfortinately ' ssh_pc.close except pexpect. timeout: print ' EXpect patterns failed ' ssh_pc.closessh_commands (' 172.172.1.1 ', ' root ', ' Fortinet ', [' uname -a ', ' hostname '])
Operation Result:
[email protected] ' s password: ==============================
Fortinet
Welcome to Ubuntu 12.04.4 LTS (gnu/linux 3.5.0-23-generic x86_64)
* documentation:https://help.ubuntu.com/
System information as of Tue Oct 11:50:25 CST 2014
System load:0.08 Users logged In:2
Usage of/: 12.4% of 28.81GB IP address for eth0:172.172.1.1
Memory usage:5% IP address for eth1:10.1.1.1
Swap usage:0% IP address for eth2:10.16.1.2
processes:218
Graph this data and manage the system at:
https://landscape.canonical.com/
175 packages can be updated.
118 updates are security updates.
New release ' 14.04.1 LTS ' available.
Run ' Do-release-upgrade ' to upgrade to it.
You have new mail.
Last Login:tue Oct-11:05:45 from 172.172.4.1
[Email protected]:~# uname-a
Uname-a
Linux dev-1-a 3.5.0-23-generic #35 ~precise1-ubuntu SMP Fri Jan 17:13:26 UTC x86_64 x86_64 x86_64 gnu/linux
[Email protected]:~# hostname
Hostname
Dev-1-a
[email protected]:~# expect patterns failed here matches to Pexpect. Timeout branch. On-line search of a lot of information, but also read the program written by others, they are in the initialization of the object, the CMD added to the pexpect.spawn command parameters, namely:
SSH_PC = Pexpect.spawn (' ssh%[email protected]%s%s '% (user,ip,cmd), timeout=5,logfile=logfile), I've tried this, and can really circumvent read () Throwing an exception and then putting the entire ssh_commands function into a for loop can also be implemented by passing a list type of CMDS. But this is equivalent to initializing one Spawn class object at a time. And I, I want to initialize a Spawn class object, through expect and Sendline Loop, issued a list type of CMDS.
However, when I uncomment the following line, the timeout exception disappears.
Ssh_pc.sendline (' exit ')
The Code of implementation passed is as follows:
Import pexpectimport sysdef ssh_commands (ip,user,passwd,commands): ip= STR (IP) user=str (user) passwd=str (passwd) #logfile =file ('%s_%s ' % (ip,user), ' W ') logfile=sys.stdout ssh_pc = pexpect.spawn (' ssh %[email protected]%s ' % (USER,IP), Timeout=5,logfile=logfile) try: match_tag = ssh_pc.expect ([' continue connecting (yes/no)? ', ' Password: '],timeout=3 ' if match_tag==0: print ' # ' *30 ssh_pc.sendline (' yes ') ssh_pc.expect (' Password: ') ssh_pc.sendline (PASSWD) elif match_tag==1: print ' = ' *30 ssh_pc.sendline (passwd) for cmd in commands: ssh_pc.expect ([' # ', Pexpect. Timeout,pexpect. EOF]) ssh_pc.sendline (cmd) ssh_pc.expect ([' # ', Pexpect. Timeout,pexpect. EOF]) ssh_pc.close ssh_pc.sendline (' exit ') print ssh_pc.read () except pexpect. eof: print ' sub process abort Unfortinately ' ssh_pc.close except pexpect. timeout: print ' exPect patterns failed ' ssh_pc.closessh_commands (' 172.172.1.1 ', ' root ', ' Fortinet ', [' uname -a ', ' hostname '])
Execution Result:
[email protected] ' s password: ==============================
Fortinet
Welcome to Ubuntu 12.04.4 LTS (gnu/linux 3.5.0-23-generic x86_64)
* documentation:https://help.ubuntu.com/
System information as of Tue Oct 12:50:53 CST 2014
System load:0.0 Users logged In:2
Usage of/: 12.4% of 28.81GB IP address for eth0:172.172.1.1
Memory usage:5% IP address for eth1:10.1.1.1
Swap usage:0% IP address for eth2:10.16.1.2
processes:218
Graph this data and manage the system at:
https://landscape.canonical.com/
175 packages can be updated.
118 updates are security updates.
New release ' 14.04.1 LTS ' available.
Run ' Do-release-upgrade ' to upgrade to it.
You have new mail.
Last Login:tue Oct-11:50:25 from 172.22.4.7
[Email protected]:~# uname-a
Uname-a
Linux dev-1-a 3.5.0-23-generic #35 ~precise1-ubuntu SMP Fri Jan 17:13:26 UTC x86_64 x86_64 x86_64 gnu/linux
[Email protected]:~# hostname
Exit
Hostname
Dev-1-a
[Email protected]:~# exit
Logout
Connection to 172.172.1.1 closed.
Hostname
Dev-1-a
[Email protected]:~# exit
Logout
Connection to 172.172.1.1 closed.
Do not understand a problem, I have ssh_pc.read () before the execution of Ssh_pc.close (), why must send another ssh_pc.sendline (' exit ') to circumvent the exception timeout. Please understand the great God pointing. Thank you.
[Python] Pexpect.spawn object Child calls read () when a timeout exception is triggered