Preface
In a real production environment, writing shell scripts will inevitably encounter some interactive interfaces, such as raid s and extensions, which require interaction, so we need to use the following non-interactive operations to achieve true shell script automation.
1. Here Document exempt from interaction
1. Overview
-
Provide a list of commands to an interactive program or command, such as a ftp, cat, or read command, using I/O redirection
-
Is an alternative to standard input, which helps script developers build input information without using temporary files, but instead generate a "file" in place and use it as standard input for a "command"
-
Here Document can also be used with non-interactive programs and commands
2. Grammar Format
command <<sign ... content #Tags are passed in directly ... sign
3. Notes
-
Markers can use any legal character (usually EOF)
-
The end marker must be top-notched, with no characters (including spaces) before or after it.
-
Spaces before and after the start tag are omitted
4. Examples
1. Implement row count statistics in an interactive way
[root@localhost ~]# wc -l <<EOF > xjj1 > xjj2 > EOF 2
(2) Receive input and print through read command
- Replace variables with actual values when writing to a file
- Then write with the cat command
[root@localhost ~]# vim xjj1.sh #!/bin/bash file="xjj3.txt" i="money" cat > $file <<EOF I'd like some $i EOF
[root@localhost ~]# . xjj1.sh #Execute script first [root@localhost ~]# ls xjj1.sh xjj3.txt [root@localhost ~]# cat xjj3.txt I'd like some money
(3) assign values to variables as a whole, and then print out the values of variables by echo command
[root@localhost ~]# vim xhh1.sh #!/bin/bash name="OMG! xjj come!" myname=$(cat <<EOF It's a beautiful day today is sunday school starts again tomorrow $name EOF ) echo $myname
[root@localhost ~]# . xhh1.sh It's a beautiful day today is sunday school starts again tomorrow OMG! xjj come!
(4) Turn off variable substitution function
- This will output as the original character, without any modifications or substitutions
[root@localhost ~]# . xhh1.sh It's a beautiful day today is sunday school starts again tomorrow $name
Create a yum source
[root@localhost ~]# cat > test.repo <<EOF > [test] > name=test > baseurl=file:///mnt > enabled=1 > gpgcheck=0 > EOF ------ Writing 2: cat <<EOF > local.repo Writing 3: tee test1.txt <<EOF
Multi-line notes
- Bash's default comment is'#', which only supports single-line comments
- The introduction of Here Document solves the problem of multiline comments
- ":" Represents an empty command to do nothing
- The contents of the intermediate markup area will not be executed and will be ignored by bash, thus achieving the effect of bulk commenting
[root@localhost ~]# . xhh1.sh OMG! xjj come!
2. Expect Automation Interaction
1. Overview
- expect is a free programming tool language that is often used to communicate between automated and interactive tasks without human intervention
- Expct requires support for the Tcl programming language. To run expect on your system, you must first install Tcl
rpm -q expect rpm -q tcl yum -y install expect #Either yum or CD-ROM installation
2. Basic Commands
(1) Script Interpreter
- The expect script first introduces a file indicating which shell is being used
#!/usr/bin/expect
②spawn
- spawn is usually followed by a Linux command that opens a session, starts a process, and tracks subsequent interactions
example: spawn passwd root ##Track the process of starting a password change
③expect
- Determines if the last input contains the specified string and returns immediately if it does, otherwise it waits for a time-out to return
- Only output from processes started by spawn can be captured
- Used to receive output after command execution and then match the expected string
④send
- Send a string to the process to simulate user input
- This command does not automatically reroute carriages, typically with \r (Enter) or \n
- Mode 1
expect "Password" {send "abc123\r"} #send section on the same line must have {}
- Mode 2
expect "Password" send "$abc123\r" #The newline send section does not require {}
- Mode 3
expect "Support multiple branches expect { #Whenever one of these situations is matched, the expect statement is exited after executing the corresponding send statement "Password 1 {send "abc123\r"}" "Password 2 {send "123123\r"}" "Password 3 {send "123123\r"}" }
Terminator
expect eof
- Indicates the end of interaction, waits for the end of execution, falls back to the original user, corresponding to spawn
- For example, switching to the root user, the expect script defaults to waiting for 10s, and when the command is executed, it defaults to staying for 10s, which automatically cutes back to the original user
interact
- When the execution is completed, the interactive state is maintained, control is given to the console, and control is left at the target terminal, at which point manual operation is possible. Commands after the interact do not work, such as the interact stays at the terminal without returning to the original terminal, such as switching to the root user, and it stays at the root user state all the time.
- For example, ssh to another server will always be in the target server terminal, not the original server back
- Note: expect eof and interact can only choose one from the other
⑥set
- The default timeout for expect is 10 seconds. Session timeout can be set with the set command or -1 if timeout is not limited
#Example: set timeout 30
⑦exp_continue
- After an exp_continue is attached to an expect judgement, it can be matched to other items in the expect judgement
- exp_continue is similar to a continue statement in a control statement in that it allows expect to continue executing instructions down
- The following example will determine whether yes/no or *password exists in the interactive output, and output yes if yes/no is matched and execute the judgment again.If *assword matches, output 123123 and end the expect statement
expect "(yes/no)" {send "yes\r"; exp_ continue; } "*password" {set timeout 300; send "123123\r";}
⑧send_user
- Send_user stands for echo command, equivalent to echo
Receive parameters
- Expct scripts can accept parameters passed from the bash command line, obtained using [lindex $argv n], where n starts at 0 and represents the first, second, and third, respectively...
- Example:
set hostname [lindex $argv 0] ##Equivalent to hostname=$1 set password [lindex $argv 1] ##Equivalent to password=$2
3.expect direct execution
- ssh5 Interactive Logon to Remote Server
[root@localhost shell]# vim expect.sh [root@localhost /home]#vim expect.sh #!/usr/bin/expect #Require expect's own interpreter, do not write as bash otherwise unrecognized spawn ssh root@192.168.126.11 #Open a program that is ssh Remote Login expect { #Capture content and send password to program when password appears "password:" { send "123456\r"; } } interact #Interactive, otherwise exit the remote server directly [root@localhost /home]#chmod +x expect.sh #Additional Execution Rights Required [root@localhost /home]#./expect.sh spawn ssh root@192.168.126.11 root@192.168.126.11's password: Last login: Wed Sep 15 22:39:40 2021 from 192.168.126.15
- Exit after performing an operation on the other server to execute the following script
[root@localhost /home]#vim expect.sh #!/usr/bin/expect spawn ssh root@192.168.126.11 expect { "password:" { send "123456\r"; } } expect "#" #When captured#When send "ls\r" #Execute ls command send "ifconfig ens33\r" #Execute ifconfig ens33 command send "exit\r" #Execute exit to log out expect eof #No interaction means ending the expect program [root@localhost /home]#chmod +x expect.sh [root@localhost /home]#./expect.sh spawn ssh root@192.168.8.129 root@192.168.126.11's password: Last login: Wed Sep 15 22:55:06 2021 from 192.168.126.15 [root@localhost ~]#ls [root@localhost ~]#ifconfig ens33 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.126.11 netmask 255.255.255.0 broadcast 192.168.126.255 inet6 fe80::2161:befa:6ffd:c44b prefixlen 64 scopeid 0x20<link> ether 00:0c:29:01:e6:0a txqueuelen 1000 (Ethernet) ...... [root@localhost ~]#exit Logout Connection to 192.168.126.11 closed.
- Reference location variable
[root@localhost /home]#vim expect1.sh #!/usr/bin/expect set user root set ip [lindex $argv 0] #Set the first location variable to ip set pass [lindex $argv 1] #Set the second location variable to the login password spawn ssh $user@$ip expect { "password:" { send "$pass\r"; } } expect "#" send "ls\r" send "exit\r" expect eof [root@localhost /home]#chmod +x expect1.sh [root@localhost /home]#./expect1.sh 192.168.126.11 123456 spawn ssh root@192.168.126.11 root@192.168.126.11's password: Last login: Wed Sep 15 22:58:16 2021 from 192.168.126.15 [root@localhost ~]#ls [root@localhost ~]#exit Logout Connection to 192.168.126.11 closed.
- Create user and set user password
[root@localhost /home]#vim user.sh #!/bin/bash username=$1 useradd $username /usr/bin/expect <<-EOF spawn passwd $username expect { #Get content and send content cannot be on the same line or execute unsuccessfully "New password" { send "123456\r";exp_continue } "Re-enter the new password" { send "123456\r"; } } EOF [root@localhost /home]#chmod +x user.sh [root@localhost /home]#./user.sh xjj spawn passwd xjj Change User xjj Password. New password: Invalid password: password less than 8 characters Re-enter the new password: passwd: All authentication tokens have been successfully updated.
summary
With expect's command for handling interactions, interactive processes such as ssh login, FTPLogin, etc. is written on a script to automate. It can be used in environments where multiple servers need to perform the same operation. It can greatly improve the efficiency of system administrators. With it, you can even execute a script to complete the building and maintenance of distributed application systems.