English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Detailed explanation of implementing Shell automation interaction with expect command

Background

There are many scenarios in Linux scripts that involve remote operations, such as remote login via ssh, remote copying via scp, and file transfer via sftp. These commands all involve the input of security passwords, and normal use of the commands requires manual input of the password and acceptance of security verification. To achieve automated remote operations, we can borrow the functionality of expect.

Expect is a free programming tool language used to communicate with automatic and interactive tasks without human intervention. Expect is constantly evolving, and with the passage of time, its functions are becoming more powerful, and it has become a powerful assistant for system administrators. Expect requires the support of the Tcl programming language, and must be installed first on the system before running expect.

Expect installation

Expect is created based on Tcl, so we should install Tcl first before installing expect.

(I) Tcl installation

Home page: http://www.tcl.tk

Download address: http://www.tcl.tk/software/tcltk/downloadnow84.tml

1.Download the source code package

wget http://nchc.dl.sourceforge.net/sourceforge/tcl/tcl8.4.11-src.tar.gz 

2.Uncompress the source code package

tar xfvz tcl8.4.11-src.tar.gz 

3.Install and configure

cd tcl8.4.11/unix 
./configure --prefix=/usr/tcl --enable-shared 
make 
make install 

Note:

1After the installation is complete, enter the root directory of the tcl source code, copy the tclUnixPort.h file under the subdirectory unix to the subdirectory generic.

2Do not delete the tcl source code temporarily, because the installation process of expect still needs it.

(II) expect installation (requires the Tcl library)

Home page: http://expect.nist.gov/

1.Download the source code package

wget http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz/download 

2.Uncompress the source code package

tar xzvf expect5.45.tar.gz 

3.Install and configure

cd expect5.45 
./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.4.11/generic 
make 
make install 
ln -s /usr/tcl/bin/expect /usr/expect/bin/expect 

expect

The core of expect is spawn, expect, send, and set.

spawn calls the command to be executed

  • expect waits for the appearance of command prompt information, that is, captures the prompt input by the user:
  • send sends the value that needs to be interacted with, replacing the manual input content of the user
  • set sets the value of a variable
  • After the 'interact' command is executed, maintain the interactive state, hand over control to the console, at this time you can manually operate. If this line is not present, after logging in, it will exit instead of staying on the remote terminal.
  • This expect eof must be added, corresponding to spawn to indicate the end of capturing terminal output information, similar to if....endif

The expect script must end with interact or expect eof, and executing an automated task usually requires expect eof.

Other settings

  • Set expect to never timeout set timeout -1
  • Set expect 300 seconds timeout, if over300 Exit set timeout if no expect content appears 300

Expect syntax

Expect uses Tcl syntax

  • A Tcl command is composed of words separated by spaces. Among them, the first word is the command name, and the rest are command parameters
    cmd arg arg arg
  • The dollar sign represents the value of a variable. In this case, the variable name is foo.
    $foo
  • Brackets execute a nested command. For example, if you want to pass the result of a command as a parameter to another command, you use this symbol
    [cmd arg]
  • Double quotes mark a phrase as a parameter of a command. The "$" symbol and brackets are still interpreted within double quotes
    "some stuff"
  • Braces also mark a phrase as a parameter of a command. However, other symbols are not interpreted within braces
    {some stuff}
  • The backslash symbol is used to refer to special symbols. For example: n represents a newline. The backslash symbol is also used to close the special meaning of the "$" symbol, quotes, brackets, and braces

Example

login.exp is used for remote login, quick usage method: login.exp "exclude" "${remote_ip}" "${remote_user}" "${remote_passwd}" "${remote_command}"

#!/usr/bin/expect -f
##########################################################
# Log in via SSH and execute commands
# Parameters:1.Use_Type [check/.execute]
#  2.SSHServerIp
#  3.SSHUser
#  4.SSHPassword
#  5.CommandList [separated by ; between multiple commands]
# Return value:
# 0 Success
#  1 Incorrect number of parameters
#  2 SSH server service is not open
#  3 SSH user password is incorrect
#  4 Connection to SSH server timed out
##########################################################
proc usage {} {
 regsub ".*/" $::argv0 "" name
 send_user "Usage:\n"
 send_user " $name Use_Type SSHServerIp SSHUser SSHPassword CommandList\n"
 exit 1
} 
## Check the number of parameters
if {[llength $argv] != 5}
 usage
}
# Set variable values
set Use_Type [lindex $argv 0]
set SSHServerIp [lindex $argv 1]
set SSHUser [lindex $argv 2]
set SSHPassword [lindex $argv 3]
set CommandList [lindex $argv 4]
#spawn ping ${SSHServerIp} -w 5
#expect {
# -nocase -re "100% packet loss" {
#  send_error "Ping ${SSHServerIp} is unreachable, Please check the IP address.\n"
#  exit 1
# }
#}
set timeout 360
set resssh 0
# Define a variable to mark whether yes confirmation is input during SSH connection
set inputYes 0
set ok_string LOGIN_SUCCESS
if {$Use_Type=="check"} {
 # Activate SSH connection, if confirmation is required to input yes, input yes, set inputYes to1Enter SSH password if needed
 spawn ssh ${SSHUser}@${SSHServerIp} "echo $ok_string"
} else {   
 spawn ssh ${SSHUser}@${SSHServerIp} "$CommandList"
}
expect {
 -nocase -re "yes/no" {
  send -- "yes\n"
  set inputYes 1
 }
 -nocase -re "assword: " {
  send -- "${SSHPassword}\n"
  set resssh 1
 }
 #-nocase -re "Last login: " { 
 #  send -- "${CommandList}\n"
 #}
 $ok_string {}
 -nocase -re "Connection refused" {
  send_error "SSH services at ${SSHServerIp} is not active.\n"
  exit 2
 }
 timeout {}}}
  send_error "Connect to SSH server ${SSHUser}@${SSHServerIp} timeout(10s).\n"
  exit 4
 }
}
#If you confirm with yes, enter the ssh password
if {$inputYes==1}
 expect {
  -nocase -re "assword: " {
   send -- "${SSHPassword}\n"
   set resssh 1
  }
 }
}
#If there is a try again or password: prompt, it means that the user password is incorrect, and exit directly.
if {$resssh==1}
 expect {
  -nocase -re "try again" {
   send_error "SSH user:${SSHUser} passwd error.\n"
   exit 3
  }
  -nocase -re "assword:" {
   send_error "SSH user:${SSHUser} passwd error.\n"
   exit 3
  }
  eof {}
 }
}
send_error -- "$expect_out(buffer)"
#-nocase -re "No such user" {
#  send_error "No such user.\n"
#  exit 5
# }
#exit

Summary

That's all for this article. I hope the content of this article has certain reference value for everyone's learning or work. If you have any questions, you can leave a message for communication. Thank you for your support of the Yell Tutorial.

Statement: The content of this article is from the Internet, the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume relevant legal liabilities. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email for reporting, and provide relevant evidence. Once verified, this site will immediately delete the infringing content.)

You may also like