Expect overview
Expect is a tool based on tcl. Expect is a tool for automatic control and testing. It mainly solves the problem of non-interaction in shell script. It's helpful for large-scale Linux operations and maintenance
In the development of Linux operations and peacekeeping, we often need remote login server to operate. The login process is an interactive process, which may require input of yes/no, password and other information. To simulate this input, you can use Expect scripts.
Basic command
send: Sends a string to a process to simulate user input
- This command can't automatically return and change lanes. Generally, r (return) is added.
expect
- An internal command of expect that determines whether the last output contains the specified string or not and returns immediately if it does, otherwise it waits for a timeout to return.
- Only the output of processes initiated by span can be captured
spawn: Start the process and track subsequent interaction information
Interaction: Stay interact ive when execution is complete and give control to the console
Timeout: Specifies a timeout time and continues to execute subsequent instructions when it expires
- The unit is: seconds.
- Timeout-1 is never timeout
- By default, timeout is 10 seconds
exp_continue
- Allow expect to continue executing instructions downward
send_user
- Echo command, equivalent to echo
argv parameter array
- Expect scripts can accept parameters passed from bash, which can be obtained using [lindex $argv n], n starting from 0, representing the first, second, and third parameters, respectively.
Expect scripts must end with an interact or expect eof, which is usually enough to perform automation tasks
- Expect eof is waiting for the end sign. A command initiated by span produces an eof tag at the end, and expect eof is waiting for that tag.
Expect syntax
Single Branch Grammar
expect "password:" {send "mypassword\r";}
Multi-branch schema grammar
send command does not have the function of carriage return and lane change. Generally, r or n should be added.
expect "aaa" {send "AAA\r"}
expect "aaa" {send "AAA\r"}
expect "aaa" {send "AAA\r"}
As long as any of the aaa or bbb or ccc matches, exit the expect statement after executing the corresponding send statement
expect {
"aaa" {send "AAA\r"}
"bbb" {send "BBB\r"}
"ccc" {send "CCC\r"}
}
exp_continue means to continue matching later, and if aaa is matched, to continue matching bbb downward after the send statement is executed
expect {
"aaa" {send "AAA\r";exp_continue}
"bbb" {send "BBB\r";exp_continue}
"ccc" {send "CCC\r"}
}
- re parameter represents matching regular expression
Expect execution
Direct execution
SSH login
First landing
Normal login
Connection rejected, ssh not open, port number incorrect, or firewall restrictions
No connection address
#!/usr/bin/expect//Expect binary file path #Timeout time set timeout 20 //20 seconds waiting time log_file test.log //log file log_user 1 //Log user #Parameter passing in set hostname [lindex $argv 0] //Adding parameter 0, statistic variable and loading position 1 parameter set password [lindex $argv 1] //Append parameter 1, statistic variable and load position 2 parameter #Tracking command spawn ssh root@$hostname //Tracking command #Capturing information and matching non-interactive execution expect { //Capture prompt information "Connection refused" exit //Discontinue after capturing rejected connection information "service not konwn" exit //Capture the service to open information and exit "(yes/no)" // Capture yes or no parameters {send "yes\r";exp_continue} //Enter yes and continue execution "*password" // Capture parameters {send "$password\r"} //Enter password parameters } #Delivery of control to the console interact //Control Transfer Console Man-made Input [root@localhost ~]# ./expect.sh 192.168.109.132 baby520./ spawn ssh root@192.168.109.132 root@192.168.109.132's password: Last login: Thu Oct 10 16:52:48 2019 from 192.168.109.10 [root@localhost ~]#
Expect execution
Embedded execution
#!/bin/bash user=$1 password=$2 #Non-interactive commands outside expect useradd $user #Start interaction expect <<-EOF //Expect start flag, standard input, equivalent to stdin spawn passwd $user expect "New*" send "$password\r" expect "again*" send "$password\r" expect eof; EOF //Expect closing statement, no blanks around EOF [root@localhost ~]# ./expect.sh 192.168.109.132 baby520./ spawn ssh root@192.168.109.132 root@192.168.109.132's password: Last login: Thu Oct 10 17:38:16 2019 from 192.168.109.133 [root@localhost ~]# exit //Logout Connection to 192.168.109.132 closed.
Case 1
Create custom users, password customization
#!/bin/bash username=$1 password=$2 useradd $username /usr/bin/expect <<-EOF spawn passwd $username expect { "New*" {send "$password\r";exp_continue} "again*" {send "$password\r"} } EOF [root@localhost ~]# ./tom.sh test2 123123 spawn passwd test2 //Change the password of user test2. //New password: //Invalid password: password less than 8 characters //Re-enter the new password: passwd: All authentication tokens have been successfully updated.
Case 2
Using expect to complete FTP login process
#!/usr/bin/expect -f set timeout 20 spawn ftp 192.168.109.133 expect "Name*" send "ftp\r" expect "Password:*" send "\r" expect "ftp>*" interact expect eof