From: http://15103850.blog.hexun.com/61380230_d.html
I. Overview
We can use Shell to implement simple control flow functions, such as loops and judgments. However, manual intervention is required for scenarios that require interaction. Sometimes we may need to implement interaction functions with interactive programs, such as telnet servers. CT is used to implement this function.
Ubuntu Forum
Keep CT is a free programming tool language used to automatically communicate with interactive tasks without human intervention. Don Libes, author of objective CT, made the following definition for objective CT when it was written in 1990: automated CT is a software suite for automatic interaction (Automated CT [is a] software suite for automatic interactive tools ). The system administrator can create scripts to provide input to commands or programs. These commands and programs are expected to be input from the terminal, generally, these inputs must be input manually. Then, you can simulate the input required by the program based on the Program prompts to execute the interactive program. It can even implement simple BBS chatbots. :)
Trusted CT is evolving. As time passes, it becomes more and more powerful and has become a powerful assistant to system administrators. Secondary CT must be supported by the Tcl programming language. To run secondary CT on the system, you must first install Tcl.
Ii. Working Principle of CT
At the simplest level, secondary CT works like a universal Chat script tool. The Chat script was first used in the UUCP network to automate specific logon sessions when computers need to establish connections.
The Chat script consists of a series of CT-send pairs: CT waits for the output to output specific characters, usually a prompt, and then sends a specific response. For example, the following Chat script waits for the standard output to show Login: String, then sends somebody as the user name, then waits for Password: prompt, and sends a response to sillyme.
Reference: login: Somebody password: sillyme
This script is used to implement a logon process and use a specific user name and password for logon.
The simplest script operation mode of secondary CT is essentially the same as the chat script operation mode.
Example: BT Wireless Network cracking tutorial
1. Implement Functions
Next we will analyze a script that responds to the CHSH command. Let's first review the interactive command format. Assume that we want to change the logon script for the user Chavez. The command interaction process required is as follows:
Reference: # CHSH Chavez
Changing the login shell for Chavez
Enter the new value, or press return for the default
Login Shell [/bin/bash]:/bin/tcsh
#
You can see that the command first outputs several lines of prompts and prompts you to enter a new logon shell. You must enter the user's logon shell after the prompt or press enter without modifying the logon shell.
2. The following is a CT script that can be used to automatically execute this command:
#!/usr/bin/expect
# Change a login shell to tcsh
set user [lindex $argv 0]
spawn chsh $user
expect "]:"
send "/bin/tcsh "
expect eof
exit
This simple script can explain the features of many CT programs. Like other scripts, the first line specifies the command program used to execute the script. Here is/usr/bin/example CT. The first line of the program is used to obtain the execution parameters of the script (which is saved in the array $ argv and is a parameter starting from 0) and save it to the variable user.
The second parameter uses the spawn command of yield CT to start the script and command session. Here the CHSH command is started. In fact, the command is run in the form of derivative sub-processes.
The subsequent trusted CT and send commands are used to implement the interaction process. The script first waits for the output to appear]: String, once the CHSH output to the feature string appears in the output (generally, the feature string is usually the feature information waiting for the input at the final prompt ). Other unmatched information will be completely ignored. When the script obtains the feature string, the secondary CT sends the/bin/tcsh and a carriage return to the CHSH command. The final script waits for the command to exit (CHSH ends). Once the EOF character indicating that the sub-process has ended is received, the secondary CT script exits.
3. determine how to respond
The Administrator often needs to respond to a command in different ways based on the current situation. We can see from the examples below that condition response can be very complex, and can be implemented simply by modifying the pre-processing script. The following example shows a more complex example of reverse CT-Send:
expect -re "\[(.*)]:"
if {$expect_out(1,string)!="/bin/tcsh"} {
send "/bin/tcsh" }
send " "
expect eof
In this example, the first round CT command now uses the-Re parameter, which indicates that the specified string is a regular expression rather than a normal string. In the above example, we look for a left square brackets (which must be escaped three times (escape), so there are three symbols, because it is a special character for regular CT and regular expression) followed by zero or multiple characters, and finally a right square brackets. Here, * indicates one or more arbitrary characters. It is stored in () because the matching result is stored in a variable to implement subsequent access to the matching result.
If a match is found, check the string contained in [] to check whether it is/bin/tcsh. If not, send/bin/tcsh to the Chsh command as the input. If yes, send only one carriage return. This simple example of sending different responses to specific situations illustrates the powerful functions of reverse CT.
In a regular expression, you can include several parts in () and access them through the expect_out array. Each part is encoded from left to right in the expression, starting from 1 (0 contains the entire matching output ). () Nesting may occur. In this case, encoding is performed from the innermost layer to the outermost layer.
4. Timeout
The prompt function with the timeout function will be described in the next round CT example. This script prompts the user to enter. If no input is made within the specified time, the script times out and returns a default response. This script receives three parameters: prompt string, default response and timeout (seconds ).
#!/usr/bin/expect
# Prompt function with timeout and default.
set prompt [lindex $argv 0]
set def [lindex $argv 1]
set response $def
set tout [lindex $argv 2]
The first part of the script is to get the running parameters and save them to internal variables.
send_tty "$prompt: "
set timeout $tout
expect " " {
set raw $expect_out(buffer)
# remove final carriage return
Cisco IOS On Unix
set response [string trimright "$raw" " "]
}
if {"$response" == "} {set response $def}
send "$response "
# Prompt function with timeout and default.
set prompt [lindex $argv 0]
set def [lindex $argv 1]
set response $def
set tout [lindex $argv 2]
This is the rest of the script. The send_tty command is used to display the prompt string, a colon, and a space on the terminal. The set timeout command sets the timeout value of all the subsequent wait CT commands for response to $ tout (the-l parameter is used to disable any timeout settings ).
The reset CT command then waits for the carriage return character to appear in the output. If you get a carriage return before the time-out, the set command will assign the user-input content to the face-changing raw. The subsequent command removes the last carriage return symbol of the user input and then assigns the value to the variable response.
Then, if the content in response is empty, set the value of response to the default value (if the user does not enter the value after the timeout or the user only enters the carriage return ). Finally, the send command adds a carriage return to the value of the response variable to the standard output.
One interesting thing is that the script does not use the spawn command. The trusted CT script interacts with any process that calls the script.
If the Script Name is prompt, it can be used in any C-style shell.
% Set a = 'prompt "Enter an answer" silence 10'
Enter an answer: test
% Echo Answer was "$"
Answer was test
The time-out period set by prompt is 10 seconds. If the time-out or the user only enters the carriage return symbol, the echo command will output
Answer was "silence"
5. A more complex example
Next we will discuss an example of a more complex round CT script, which uses more complex control structures and a lot of complex interaction processes. This example is used to send the write command to any user. The message sent is from a file or from keyboard input.
#!/usr/bin/expect
# Write to multiple users from a prepared file
# or a message input interactively
if {$argc<2} {
send_user "usage: $argv0 file user1 user2 ... "
exit
}
The send_user command is used to display the standard output of the help information to the parent process (usually the user's shell.
set nofile 0
# get filename via the Tcl lindex function
set file [lindex $argv 0]
if {$file=="i"} {
set nofile 1
} else {
# make sure message file exists
if {!=1} {
send_user "$argv0: file $file not found. "
exit }}
This part of the implementation process script startup parameters must be a file name that stores the message to be sent or the "I" command that indicates that the message is sent and eliminated using interactive input.
The variable file is set to the value of the first parameter of the script. It is implemented by using the Tcl function lindex. This function obtains a specific element from the list/array. [] Is used to use the return value of the lindex function as the parameter of the set command.
If the first parameter of the script is "I" in lower case, the nofile variable is set to 1. Otherwise, you can call the Tcl function isfile to verify that the file specified by the parameter exists, if it does not exist, the system reports an error and exits.
We can see that the if command is used for logical judgment. This command is followed by the judgment condition and executed within {} after the judgment condition. If the condition is false, the program block after else is run.
set procs {}
# start write processes
for {set i 1} {$i<$argc}
{incr i} {
spawn -noecho write
[lindex $argv $i]
lappend procs $spawn_id
}
The last part uses the spawn command to start the write process to send messages to users. Here we use the for command to implement the loop control function. The loop variable is set to 1 first, and then increments accordingly. The loop body is the last {} content. Here we use the second and subsequent parameters of the script to execute a write command on the spawn and use each parameter as the user name for sending the message. The lappend command uses the internal variable $ spawn_id of the process ID that saves each spawn to construct a process ID list in the variable procs.
if {$nofile==0} {
setmesg [open "$file" "r"]
} else {
send_user "enter message,
ending with ^D: " }
Finally, the script opens the message file based on the value of the variable nofile or prompts the user to enter the message to be sent.
set timeout -1
while 1 {
if {$nofile==0} {
if {[gets $mesg chars] == -1} break
set line "$chars "
} else {
expect_user {
-re " " {}
eof break }
set line $expect_out(buffer) }
foreach spawn_id $procs {
send $line }
sleep 1}
exit
The above code shows how the actual message text is sent through an infinite loop while. The if statement in the while LOOP determines how the message is obtained. In non-interactive mode, the next row of content is read from the message file, and the while loop ends when the file content ends. (The break command is used to terminate the loop ).
In interactive mode, the expect_user command receives messages from the user. When the user inputs ctrl + D, the input ends, and the loop ends at the same time. In both cases, the variable $ line is used to save the content of the next message. When it is a message file, the carriage return will be appended to the end of the message.
Foreach cyclically traverses all spawn processes. The idnumbers of these processes are stored in the list variable $ procs To communicate with each process separately. The send command is a foreach loop body that sends a row of messages to the current write process. At the end of the while loop is a sleep command, which is mainly used to process non-interactive modes to ensure that messages are not sent to each write process too quickly. When the while LOOP exits, the reverse CT script ends.
Simple Example:
#!/usr/bin/expect
set timeout 30
spawn ssh -l user x.x.x.x
expect {
"password: " {send "mypasswd\r"}
timeout {
send_user "timeout"
exit 1
}
eof {
send_user "endofsession"
exit 1
}
}
set timeout 1
expect "localhost ~]$"
send "cd test; nohup ./a.out &\r"
#interact
expect eof
The script automatically logs on to the xxxx machine and runs the corresponding command to return to the current terminal. Replace user and mypasswd with the actual user and password respectively.
Note: Keep CT local files must use absolute paths