Recent project requirements, need to write some shell script interaction, the pipeline is not enough time, expect can be very good to implement the interaction between the script, search for information, found that many articles on the Web are reproduced, I think this article is also good, so simple changes to take over and share with you ~
1. Expect isSpawn: Add the shell commands you need to execute, such as spawn sudo touch testfile
1.3 Expect:only spawn executed command results will be captured by expect., because Spawn will start a process, only the relevant information of this process will be captured, mainly including:prompt information for standard input,Establishment of the account under Linux:
filename:account.sh, you can use./account.sh Newaccout to execute;
1 #!/usr/bin/expect
2
3 Set passwd"MYPASSWD" "This is the password you set "
4 Set Timeout 60
5
6 if {$ARGC! = 1} {
7 Send "usage./account.shExit
3 ·
10
One set user [lindex $argv [$ARGC-1]]
12
Spawn sudo useradd-s/bin/bash-g mygroup-m $user
14
Expect {
"Assword" {
Send_user "sudo now\n"
Send "$PASSWD \ n"
19Exp_continue
20}
Eof
22 {
2324}
25}
26
Spawn sudo passwd $user
Expect {
"Assword" {
Send "$PASSWD \ n"
31Exp_continue
32}
Eof
34 {
Send_user "EOF"
36}
37}
38
Spawn sudo smbpasswd-a $user
Expect {
"Assword" {
Send "$PASSWD \ n"
43Exp_continue
44}
Eof
46 {
Send_user "EOF"
48}
49}
3. Note the point:
Line 3rd: The method of assigning a value to a variable;
Line 4th: By default, timeout is 10 seconds;
Line 6th:Test, no need to add-s can also;
Line 15th: In general, if you do two consecutive expect, then the actual serial execution, in the case of the structure is executed in parallel, mainly to see which one to match, in this case, if you write a serial,
Expect "Assword"
Send "$PASSWD \ n"
Expect EOF
Send_user "EOF"
Then the first time will run correctly because the first sudo requires a password;The second run time because the password has been lost (by default, the sudo password is entered again for 5 minutes), the user will not be prompted to enter, so the first expect will not match to Assword, It is also important to note that if the Spawn command has an interactive question but the expect does not match, then the program will wait for the timeout setting, but if spawn directly sends EOF, which is the case, then expect "Assword" Will not wait, and go directly to execute expect EOF.
At this time will be reported Expect:spawn ID exp6 not open, because there is no spawn in the execution, the subsequent expect script will not be executed for this reason, so for such a command like Sudo, it is best to use a parallel way of processing;
Line 17th: Just a user hint, can be deleted;
Line 18th: send password to the spawn process;
Line 19th: Make the spawn process match to one after the next to match the interactive hints;
Line 21st:EOF is a must to match, at the end of the spawn process will send EOF to expect, if not to match, sometimes can also run, such as sleep how many seconds before going to spawn the next command, but do not rely on this behavior, it is possible today, can not be used tomorrow;
4. Other
The following example is special and cannot be expect EOF throughout the process:
1 #!/usr/bin/expect
2
3 Set Timeout 30
4 Spawn SSH 10.192.224.224
5 expect "Password:"
6 Send "mypassword\n"
7 Expect "*$"
8 send "mkdir tmpdir\n"
9 expect "*$"
This example is actually using SSH to log on to the remote machine, and to create a directory on the remote machine, we see that after we enter the password does not go to expect EOF, this is because SSH this spawn does not end, and the manual operation when SSH will not actually end itself unless you exit ; So you can only expect Bash's prompt, of course, it can also be a machine name, so as to be able to create a directory remotely.
Note, please do not use spawn mkdir tmpdir, this will make the previous spawn that SSH end, then your tmpdir will be set up in this machine.
Of course, the actual situation may ask you to confirm SSH key, can be processed by the parallel expect, not more than repeat.
5. I think bash is very strong in many cases, so it may be better to use expect only to master these, and others if you can go to Google again.
6. Example: The following script is completed on a single server SCP task.
1: #!/usr/bin/expect
3:set Timeout 10
4:set host [lindex $ARGV 0]
5:set username [lindex $argv 1]
6:set Password [lindex $argv 2]
7:set Src_file [lindex $argv 3]
8:set Dest_file [lindex $argv 4]
11:expect {
: "(yes/no)?"
: {
: "yes\n"
: "$password \ n"}
: }
: " *assword:"
: {
: "$password \ n"
: }
: }
23:expect EOF
Note the first line of the code, which specifies the path to the expect, is the same as the shell script, which specifies where the program should go to find the appropriate startup program at execution time. The code starts with a timeout of 10 seconds, and if you encounter an exception that is not specified in the code while performing the SCP task, the execution of the script automatically terminates after waiting 10 seconds.
Spawn represents the statement executed at the local terminal, and after the statement begins execution, expect starts capturing the terminal's output information and then makes the corresponding operation. The captured (yes/no) content in the expect code is used to complete the operation of saving the key the first time the target host is accessed. with this sentence, the mandate of the SCP reduced the situation of disruption. The expect EOF at the end of the code corresponds to spawn, which indicates the termination of the capture terminal output information.
With this expect code, you can only complete the SCP task for a single remote host. If you need to Implement a bulk SCP task , you will need to write a shell script to invoke this expect.
1: #!/bin/sh
2:
3:list_file=$1
4:src_file=$2
5:dest_file=$3
While Read line
Do
9: ' {print '} '
Ten: ' {print $} '
One: ' {print $} '
: "$host _ip"
/expect_scp $host _ip $username $password $src _file $dest _file
15:done
A very simple code that specifies 3 parameters: the location of the list file, the local source file path, and the remote host destination file path. It is necessary to note that the list file specifies the remote host IP, user name, and password, which need to be written in the following format:
IP username Password
The middle is separated by a space or TAB key, the information of multiple hosts needs to write multiple lines of content.
This specifies the information for both remote hosts. Note that if you have special characters such as "$" or "# " in the remote host password, you will need to add an escape character to the match either when you write the list file , otherwise expect will enter the wrong password when executing.
For this shell script, save as batch_scp.sh file, and just save the EXPECT_SCP file and list file (defined as hosts.list file bar) in the same directory, execute the following way to enter the command:
./batch_scp.sh./hosts.list/root/src_file/root/destfile
===============================================================================
Let's take a look at some of the internal parameters of expect:
exp_continue [-continue_timer]
The command exp_continue allows expect itself to continue executing rather than returning as it normally would. By default Exp_continue resets the timeout timer. The-continue_timer flag prevents timer from being restarted.
Exp_version [[-exit] version]
is useful for assuring, the script is compatible with the current version of Expect.
with no arguments, the current version of Expect is returned. This version is encoded in your script. If you actually know that is not the using features of recent versions, you can specify an earlier version.
Specific usage can also be viewed in documents ~
#!/bin/sh
# \
EXEC expect--"$" ${1+ "[email protected]"}
Exp_version-exit 5.0
If {$ARGC!=2} {
Send_user "usage:remote-exec command password\n"
Send_user "Eg. remote-exec \ "ssh[email protected]Ls\; echo done\ "password\n"
Send_user "or:remote-exec \" Scp/local-file[email protected]:/remote-file\ "password\n"
Send_user "or:remote-exec \" SCP[email protected]:/remote-file local-file\ "password\n"
Send_user "or:remote-exec \" Rsync--rsh=ssh/local-file[email protected]:/remote-file\ "password\n"
Send_user "Caution:command should be quoted.\n"
Exit
}
Set cmd [lindex $argv 0]
Set password [lindex $argv 1]
Eval Spawn $cmd
Set Timeout 600
While {1} {
Expect-re "is sure you want to continue connecting (yes/no)?" {
# First Connect, no public key in ~/.ssh/known_hosts
Send "yes\r"
}-re "Assword:" {
# already have public key in ~/.ssh/known_hosts
Send "$password \ r"
}-re "Permission denied, please try again." {
# Password not correct
Exit
}-re "kb/s| MB/S "{
# User equivalence already established, no password is necessary
Set Timeout-1
}-re "File list ..." {
# rsync started
Set Timeout-1
}-re "Bind:address already in use" {
# for local or remote port forwarding
Set Timeout-1
}-re "is a directory| No such file or directory "{
Exit
}-re "Connection refused" {
Exit
} Timeout {
Exit
} EOF {
Exit
}
}
Note usage:
Eg. Remote-exec "SSH [email protected] ls; echo Done "password
Or:remote-exec "Scp/local-file [email protected]:/remote-file" password
Or:remote-exec "SCP [email protected]:/remote-file local-file" password
Or:remote-exec "rsync--rsh=ssh/local-file [email protected]:/remote-file" password
Caution:command should be quoted.
Transferred from: http://blog.csdn.net/nero_g/article/details/53945654
Shell Scripting Interaction: Expect learning notes and examples