Expect detailed
The expect command is simply to implement tools that automatically interact in interactive software through its built-in commands.
SSH can be used in conjunction with the Spawn command to achieve automatic SSH login. And because it can be written in the script judgment, assignment and other logic, with high flexibility.
problem
How do I ssh from machine A to machine B, and then execute the commands on machine B? How do I automate it?
Four commands
The key four commands in expect are send,expect,spawn,interact.
Send: For sending a string to a process
Expect: Receive string from process
Spawn: Start a new process
Interact: Allow user interaction
1. Send command
The Send command receives a string parameter and sends the parameter to the process.
expect1.1> send "Hello world\n"
Hello World
2. Expect command
(1) Basic knowledge
The expect command is just the opposite of the Send command, and expect is usually used to wait for feedback from a process. Expect can receive either a string parameter or a regular expression parameter. In conjunction with the Send command above, we can now look at one of the simplest interactive examples:
Expect "hi\n"
Send "Hello there!\n"
These two lines of code mean: Wait for the hi and newline keys from the standard input and output Hello there to the standard output.
Tips: $expect _out (buffer) stores all input,< to the expect $expect _out (0,string) > stores input that matches to the expect parameter.
For example, the following procedure:
Expect "hi\n"
Send "You typed < $expect _out (buffer) >"
Send "but I only expected < $expect _out (0,string) >"
When entering in the standard input
Test
Hi
Yes, the results of the operation are as follows
You typed:test
Hi
I only Expect:hi
(2) Mode-action
Expect's most commonly used grammar is the mode-action from the TCL language. This syntax is extremely flexible, and we'll explain each of the various syntaxes below.
Single branch mode syntax:
Expect "HI" {send "you said HI"}
Match to Hi, will output "you said HI"
Multi-branching mode syntax:
Expect "HI" {send "you said Hi\n"}\
"Hello" {send "Hello yourself\n"}\
"Bye" {send "that is unexpected\n"}
Performs the corresponding output when matching to any one of the Hi,hello,bye strings. Equivalent to the following wording:
Expect {
"HI" {send "you said Hi\n"}
"Hello" {send "Hello yourself\n"}
"Bye" {send "that is unexpected\n"}
}
3. Spawn command
All of the demos above are interacting with the standard input and output, but we expect him to interact with a process. The SPAWM command is used to start a new process. Both the send and expect commands after spawn interact with the process that spawn opens. Combined with the send and expect commands above, we can look at more complex sections of the program.
Set Timeout-1
Spawn FTP ftp.test.com//Open a new process that users connect to a remote FTP server
Expect ' name '//process returns Name
Send "user\r"//input to process anonymous\r
Expect "Password:"//Process return Password: when
Send "123456\r"//input to process don@libes.com\r
Expect "ftp>"//Process returns ftp>
Send "binary\r"//input to process binary\r
Expect "ftp>"//Process returns ftp>
Send "Get test.tar.gz\r"//Enter get test.tar.gz\r to process
The purpose of this code is to log on to the FTP server FTP ftp.uu.net and download the file test.tar.gz on the server in a binary way. Detailed comments are available in the program.
4.interact
So far, we have been able to combine spawn, expect, send automation to complete a lot of tasks. But how to get people to intervene in the process at the right time. For example, when you download the ftp file, you can still stay in the FTP command line State for manual execution of subsequent commands. Interact can achieve these goals. The demo below allows users to interact after automatically logging in to FTP.
Spawn FTP ftp.test.com
Expect "Name"
Send "user\r"
Expect "Password:"
Send "123456\r"
Interact
Solving method
The above mentioned:
How do I ssh from machine A to machine B, and then execute the commands on machine B? How do I automate it?
The following script implements log on to machine B from Machine A, then executes the PWD command on machine B and stays on the B machine, waiting for the user to interact. Please refer to the above for specific meaning.
#!/home/tools/bin/64/expect-f
Set Timeout-1
Spawn ssh $BUser @ $BHost
Expect "*password:" {send "$password \ r"}
Expect "$*" {send "pwd\r"}
Interact
Instance
Objective
A period of time before the work of the machine replaced by Ubuntu + 128G SSD + 8G memory desktop, and finally embarked on the use of Linux Office Road, in general, Ubuntu is still more smoothly than I imagined, its "apt-get-style" package management, installation software is very convenient, Apt-get Install XXX can be installed. The only drawback is that the bank's "U shield" and so does not support Linux, so the use of net silver is slightly inconvenient.
In return, the company has done one thing after the change of desktop is to unify the testing environment in the company, all the test environment machine Unified into the computer room with the way of virtual machine Unified Management (happy). In order to develop the test at a later time, the project team has applied for multiple sets of test environments, such as: development environment: The environment for each iterative self-test of the developer. Test environment: A test environment with stable and online code synchronization, typically used to demonstrate or service other applications in the test environment. In addition, there is a set of performance testing environment. The problem with so many environments is that every time you need to update the environment: update code, restarting Tomcat requires SSH to a machine. This is actually a waste of time repetitive labor, usually, this kind of thing can be solved using code. This is our protagonist today: expect.
Demo examples are as follows:
#!/usr/bin/expect-f # #声明使用哪种解析器解析该脚本, if expect is not installed, use Apt-get install expect installation
if {[Llength $argv] < 1} {# # $ARGV a parameter array to execute the script, determine the length to decide whether to continue
Puts "Usage: $argv 0 need ssh IP"//expect echo,system.out.println ()
Exit 1
}
Set Envs [lindex $argv 0] # #将数组中的第一个参数赋值给 Envs
Set Timeout 30//set timeout of 30 seconds to wait for terminal response
if {$envs = = {# #注意 if and {There is a space between {and $envs, there is a space between the equals sign, there are spaces before and after 61, and there are spaces in the space!!!.}
Set IPs xxx.xx.xxx.61
}
if {$envs = = 141} {
Set IPs xxx.xx.xxx.141
}
if {$envs = = 136} {
Set IPs xxx.xx.xxx.136
}
Spawn ssh root@ $ips # #执行ssh命令实现登陆
Expect {
# #第一次登陆的时候, ask if there is a local save the key, carefully you should find that the match here is a regular, Jiang said, only matching connecting is also possible.
"Are you sure your want to continue connecting (yes/no)?" {send ' yes\r '}
"Password:" {send "cdyanfa\r"}# #保存过一次后, it will return directly to the need for the password phase. Use the Send command to send the password.
}
Interact # #是Expect用来打开用户与产生进程之间通信的命令, to put it simply is to keep the remote server terminal at the current terminal after landing, instead of shutting down the remote terminal.
Just a few lines of command to simplify the operation of the daily repeated n times to a row, is useful for improving efficiency.