First, the Primer
Pexpect
The program is mainly used for the simulation of human-machine dialogue, that is, the system asked questions, people to answer yes/no, or account login input user name and password and so on. Because this situation is so much and tedious, many languages have their own implementations. The first Expect was implemented by the TCL language, so later Expect were roughly referenced to the initial usage and process, and the overall general process consisted of:
- Run the program
- The procedure requires human judgment and input
- Expect by keyword match
- Send a conforming string to a program based on a keyword
TCL language implementation of the Expect function is very powerful, I used it to implement a firewall device complete test platform. Also because it is easy to use, a wide range, almost all scripting languages have implemented a variety of similar and expect functions, they are different, but the principle of the difference is not small
Pexpect is the class Expect implementation of the Python language. From my point of view, it is functionally related to the implementation of the TCL language there are still some gaps, such as no buffer_full events, such as no expect before/after events, but to do the general application is enough.
Second, the basic use of the process
pexpect
The use of the following, is around 3 key commands to do:
- First use Spawn to execute a program
- Then use expect to wait for the specified keyword, which is the executed program to print to the standard output
- Finally, when the keyword is found, send the string to the program according to the keyword using the Send method.
The first step only needs to be done once, but in the program you will continue to cycle through the second to third step to complete the work step-by-step. After mastering this concept, the use of Pexpect is easy. Of course Pexpect not only these 3 methods, there are actually many other peripheral methods, we are one to illustrate
Iii. apispawn ()-Execution procedure
spawn()
method is used to execute a program that returns the operation handle of the program, which can be manipulated later by manipulating the handle:
process = pexpect.spawn('df -h')
Process is the spawn () of the program operation handle, and then all the operation of the program is based on this handle, so it can be said to be the most important part. Try to give it a short name, otherwise the program will be more than a dozen words. -
Note: Spawn (), or pexpect, does not translate any special characters such as | * Characters have special meanings in the shell of Linux, but they are not translated in Pexpect, and it is easy to make a mistake if you want to use the correct meaning of these symbols in a Linux system and you must add the shell to run them.
The right way:
import pexpectprocess = pexpect.spawn('df -h')print(process.expect(pexpect.EOF)) # 打印index
Timeout-time-out
Default value: 30 (units: seconds)
Specifies the default time-out for the program. After the program is started output, we will also check in the script whether the keyword is known and processed, if not found in the specified time the program will be returned with an error.
Maxread-Cache Settings
Default value: 2000 (unit: Character)
Specifies how much data to read from the command output at once. If you set a larger number, the number of times you read the data from the TTY is less.
A setting of 1 indicates that the read cache is turned off.
Setting larger values increases the performance of reading large amounts of data, but wastes more memory. This value is set up to work with searchwindowsize to provide more functionality.
The size of the cache does not affect what is obtained, that is, if a command output exceeds 2000 characters, the previously cached characters are not lost, but are placed elsewhere, and when you use Self.before (where self represents the instance of Spawn), the full output can be obtained.
Searchwindowsize-Pattern matching threshold
Default value: None
The searchwindowsize parameter is used in conjunction with the Maxread parameter, which is more subtle in its functionality, but can significantly reduce the time to match when there are many characters in the cache.
By default, expect () matches the specified keyword: each time a character is acquired in the cache, a regular expression is matched to all content in the entire cache, and you can imagine how low the performance would be if the program was returned in a particularly high number of cases.
Setting the value of Searchwindowsize indicates how many characters are received at one time before the expression is matched once, for example, there is now a command with a large number of outputs, but the matching keyword is the standard FTP prompt ftp>, obviously to match only 5 characters (including spaces), But by default every time expect get a new character to match the characters from the beginning, if the cache already has 1W characters, one time from the inside match is very consumption of resources, this time can be set searchwindowsize=10, so expect It will only match the keywords from the latest (last acquired) 10 characters, which can significantly improve performance if the values are set appropriately. Do not worry about whether the characters in the cache will be discarded, no matter how many outputs, as long as they do not time out will always get all the characters, the setting of this parameter only affects the matching behavior.
This parameter is typically set in the expect () command, and the Pexpect 2.x version appears to have a bug that is not set to take effect in spawn.
LogFile-run output control
Default value: None
When a file handle is specified for the logfile parameter, all content obtained from standard input and standard output is written to this file (note that the write is copy), and if a file handle is specified, The file (flush) will be flushed each time the command is sent to the program (Process.send).
Here's a very important tip: if you want to see the output in the spawn process, you can write the output to the sys.stdout, such as:
process = pexpect.spawn("ftp sw-tftp", logfile=sys.stdout)
In this way, you can see the input and output during the entire program execution, which is good for debugging.
There is one more example:
process = pexpect.spawn("ftp sw-tftp")logFileId = open("logfile.txt", 'w')process.logfile = logFileId
Note: The LogFile.txt file contains both the output of the program runtime and the content that spawn sends to the program, sometimes you may not want this, because some content appears 2 times, then there are 2 important logfile correlation parameters:
Logfile_read-Get the content of standard output
Default value: None
Record all the content returned in the execution program, that is, remove the command you sent out, and just include the part of the command result:
process.logfile_read = sys.stdout
The above statement will print all the output of the program execution on the screen, but usually does not include the commands you send to the program, but most of the programs have a callback mechanism, such as when the command is sent to the device not only to receive the command string, but also in reverse on your terminal to display the string to let you know which characters are entered, This is the way it will be read. Only those things that will not be echoed Logfile_read will not be able to get, such as when entering a password.
Logfile_send-Get the content sent
Default value: None
Record all content sent to the executing program
process.logfile_send = sys.stdout
Iv. pexpect implementation of SSH operation
#-*-Coding:utf-8-*-#!/usr/bin/pythonimport pexpectdef Login_ssh_password (port,user,host,passwd): "' Function: An automated user password to implement pexpect implementation SSH login "if port and user and host and passwd:ssh = Pexpect.spawn (' ssh-p%s%[EMAIL&N bsp;protected]%s '% (Port,user, host)) i = ssh.expect ([' Password: ', ' Continue connecting (yes/no)? '), timeout=5) if i = = 0:ssh.sendline (passwd) elif i = = 1:ssh.sendline (' yes\n ') # Interactive authentication S Sh.expect (' Password: ') ssh.sendline (passwd) index = Ssh.expect (["#", Pexpect. EOF, Pexpect. TIMEOUT]) If index = = 0:print ("Logging in as root!") Ssh.interact () elif index = = 1:print ("Logging process exit!") Elif index = = 2:print ("Logging timeout exit") Else:print ("Parameter error!") def login_ssh_key (keyfile,user,host,port): ' function: An automated key for implementing Pexpect implementation ssh ' if port and user and host and keyfile: SSH = Pexpect.spaWN (' ssh-i%s-p%s%[email protected]%s '% (Keyfile,port,user, host)) i = Ssh.expect ([Pexpect. TIMEOUT, ' Continue connecting (yes/no)? '], timeout=2) if i = = 1:ssh.sendline (' yes\n ') index = Ssh.expect (["#", Pexpect. EOF, Pexpect. TIMEOUT]) Else:index = Ssh.expect (["#", Pexpect. EOF, Pexpect. TIMEOUT]) If index = = 0:print ("Logging in as root!") Ssh.interact () elif index = = 1:print ("Logging process exit!") Elif index = = 2:print ("Logging timeout exit") Else:print ("Parameter error!") def main (): "Main function: Implement two different ways of logging in ' ' ' Login_ssh_password (' + ', ' root ', ' 10.211.55.12 ', ' admin ') # Login_ssh_key (keyfile= "/tmp/id_rsa", port= ', user= ' root ', host= ' 192.168.1.101 ') if __name__ = = "__main__": Main ()
Python's Pexpect detailed