Shell programming--Here Document free interaction and Expect automated interaction


1. Here Document is free of interaction

1 Overview

  • Use I/O redirection to provide a list of commands to interactive programs or commands, such as ftp, cat or read commands
  • It is a substitute for standard input, which can help script developers not to use temporary files to construct input information, but directly generate a "file" on the spot and use it as standard input for "commands"
  • Here Document can also be used with non-interactive programs and commands

2. Grammar format

命令 <<标记
...
内容    #标记直接是传入内容
...
标记

3. Matters needing attention

  • Mark can use any legal characters (usually use EOF)
  • The ending mark must be written in the top grid without any characters in front
  • There can be no characters (including spaces) after the ending tag
  • The spaces before and after the opening tag will be omitted

4. Example

4.1 Interaction-free mode to realize the statistics of the number of rows

  • Put the content to be counted between the tags "EOF"
  • Pass the content directly to wc -l for statistics
[root@localhost ~]# wc -l <<EOF
> xcf1
> xcf2
> EOF
2

mark

4.2 Receive input and print through the read command

  • The input value is the part between the two EOF tags
  • Assign value directly to variable i
[root@localhost ~]# read i <<EOF
> hello xcf~
> EOF
[root@localhost ~]# echo $i
hello xcf~

mark

4.3 Set password for user through passwd

[root@localhost ~]# useradd xcf123
[root@localhost ~]# passwd xcf123 << EOF
123123
123123
EOF
更改用户 xcf123 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。

mark

4.4 Support variable substitution

  • When writing the file, the variable will be replaced with the actual value
  • Then combine the cat command to complete the writing
[root@localhost shell]# vim zxc1.sh

#!/bin/bash

file="xcf1.txt"
i="chicken"
cat > $file <<EOF
I'd like some $i
EOF
[root@localhost shell]# . zxc1.sh 
[root@localhost shell]# ls
xcf1.txt  zxc1.sh
[root@localhost shell]# cat xcf1.txt 
I'd like some chicken

mark
mark

4.5 Assign a value to the variable as a whole, and then print out the variable value through the echo command

[root@localhost shell]# vim zxc2.sh

#!/bin/bash

name="OMG! xucheng come!"
myname=$(cat <<EOF
It's a beautiful day
Today is Sunday
School starts again tomorrow
$name ~
EOF
)
echo $myname
[root@localhost shell]# . zxc2.sh 
It's a beautiful day Today is Sunday School starts again tomorrow OMG! xucheng come! ~

mark
mark

4.6 Turn off the function of variable substitution

  • This will output the characters as they are
  • Without any modification or replacement
    mark
    mark

4.7 Remove the TAB character before each line

  • Not very useful, knowing that this usage can remove the tab character in each line
    mark
    mark

4.8 Multi-line comments

  • Bash's default comment is "#", this comment method only supports single-line comments
  • The introduction of Here Document solves the problem of multi-line comments
  • ":" represents an empty command that does nothing
  • The content of the middle mark area will not be executed and will be ignored by bash, so the effect of batch comments can be achieved
    mark
    mark

Two, Expect automated interaction

1 Overview

  • expect is a free programming tool language, commonly used to realize automatic and interactive tasks to communicate without human intervention
  • expect needs the support of Tcl programming language. To run expect on the system, Tcl must be installed first
yum -y install tcl

yum -y install expect

2. Basic commands

2.1 Script interpreter

  • The file is first introduced in the expect script to indicate which shell is used
#!/usr/bin/expect

2.2 spawn

  • Spawn is usually followed by a Linux execution command, which means to open a session, start the process, and track subsequent interaction information
例: spawn passwd root          ##跟踪启动更改用户密码的进程

2.3 expect

  • Determine whether the last input result contains the specified string, if there is, return immediately, otherwise, wait for the timeout period to return
  • Can only capture the output of the process started by spawn
  • Used to receive the output after the command is executed, and then match the expected string

2.4 send

  • Send a string to the process to simulate user input
  • This command cannot automatically enter and line feed, usually add \r (carriage return) or \n
  • method one
expect “密码” {
    
    send “abc123\r”}
##同一行send部分要有{}
  • Way two
expect “密码”
send “$abc123\r”
##换行send部分不需要有{}
  • Way three
expect “支持多个分支

expect  {
    
            ##只要匹配了其中一个情况,就执行相应的send语句后退出该expect语句
"密码1 {send "abc123\r"}"
"密码2 {send "123123\r"}"
"密码3 {send "123123\r"}"
}

2.5 Terminator

expect eof
  • Indicates the end of the interaction, waiting for the execution to end, returning to the original user, corresponding to spawn
  • For example: switch to the root user, the expect script waits for 10s by default. After executing the command, it will automatically switch back to the original user after it stays for 10s by default.
interact
  • After the execution is completed, the interactive state is maintained, and the control is transferred to the console. It will stay at the target terminal. At this time, it can be manually operated. The commands after the interact do not work. For example, the interact will remain in the terminal instead of returning to the original terminal. , Such as switching to the root user, will always be the root user
  • For example, ssh to another server will always be at the target server terminal instead of switching back to the original server
  • Note: Expect eof and interact can only choose one

2.6 set

  • The default timeout time of expect is 10 seconds. The session timeout time can be set through the set command. If the timeout time is not limited, it should be set to -1
##例:
set timeout 30

2.7 exp_continue

  • exp_continue is appended to a certain expect judgment item, so that after the item is matched, it can continue to match other items in the expect judgment sentence
  • exp_continue is similar to the continue statement in the control statement, which means that expect continues to execute instructions downward
  • The following example will determine whether there is yes/no or *password in the interactive output. If it matches yes/no, output yes and execute the judgment again; if it matches *assword, output 123123 and end the expect statement
expect
"(yes/no)" {
    
    send "yes\r"; exp_ continue; }
"*password" {
    
    set timeout 300; send "123123\r";}

2.8 send_user

  • send_ user means echo command, equivalent to echo

2.9 Receive parameters

  • The expect script can accept the parameters passed from the bash command line, and use [lindex $argv n] to get it, where n starts from 0 and represents the first, second, third...
  • Example:
set hostname [lindex $argv 0]
##相当于hostname=$1
set password [lindex $argv 1]
##相当于password=$2

3.expect direct execution

  • Take SSH as an example:
    • $argv 0 represents the position variable $1
    • $argv 1 represents the position variable $2
    • #!/usr/bin/expect is the path of the Expect binary file
[root@localhost shell]# vim zxc11.sh 

#!/usr/bin/expect
#设置超时时间
set timeout 20
#开启日志
log_file test.log
#显示信息
log_user 1
#定义变量
set hostname [lindex $argv 0]
set password [lindex $argv 1]
#追踪指令
spawn ssh root@${hostname}
#捕捉提示信息
expect {
    
    
        "connecting (yes/no)"
        {
    
    send "yes\r";exp_continue}
        "*password:"
        {
    
    send "${password}\r";}
}
#转交控制权
interact

mark

4.expect embedded execution

  • Integrate the expect process into the Shell to facilitate execution and processing
  • Create user and set password
#! /bin/bash
user=$1
password=$2
#非交互命令放在expect外面
useradd $user
#开始免交换执行
/usr/bin/expect <<-EOF
#expect开始标志,-去掉制表符
spawn passwd $user
#开启-一个进程跟踪passwd命令,expect只能捕捉该进程信息
expect "新的*"
send "$ {password}\r" .
expect "重新*"
send "$ {password} \r"
expect eof
EOF
  • Take SSH as an example:
#!/bin/bash
  hostname=$1
  password=$2
  /usr/bin/expect<<-EOF
  spawn ssh root@${hostname}
  expect {
      "(yes/no)"
      {send "yes\r";exp_continue}
      "*password"
      {send "$password\r"}
  }
  expect "*]#"
  send "exit\r"
  expect eof
EOF		'Expect结束标志,EOF前后不能有空格'

5. Realize SSH automatic login

[root@localhost shell]# vim zxc12.sh 

#!/usr/bin/expect
set timeout 15
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh root@${hostname}
expect {
    
    
        "connection refused" exit
        #连接失败情况,比如对方ssh服务关闭
        "Name or service not known" exit
        #找不到服务器,比如输入的IP地址不正确
        "to continue"{
    
    send "yes\r";exp_continue}
        "password:"{
    
    send "${password}\r";}
}
interact
#携带interact参数表示登录成功后将控制台交给用户,否则登录完成后将退出
exit

mark

6. Create disk without interaction

  • First manually add a disk in the virtual machine off state, and then power on
    mark
  • Scripting
[root@localhost ~]# vim disk.sh


#!/bin/bash

disk=$1

/usr/bin/expect <<-EOF

spawn fdisk $disk

expect "命令" {
    
    send "n\r"}
expect "Select" {
    
    send "\r"}
expect "分区" {
    
    send "\r"}
expect "起始" {
    
    send "\r"}
expect "Last" {
    
    send "\r"}
expect "命令(输入 m 获取帮助):" {
    
    send "w\r"}
expect eof
EOF
partprobe
mkfs.xfs $disk -f &> /dev/null

if [ $? -eq 0 ]
    then
    echo -e "\033[31m 磁盘格式化完成 \033[0m"
    mkdir $disk.1
    mount $disk $disk.1
    df -h
    else
    echo "格式化失败,脚本有bug"
fi
  • Check if the packages mentioned at the beginning of this article are installed
[root@localhost ~]# rpm -q tcl
tcl-8.5.13-8.el7.x86_64
[root@localhost ~]# rpm -q expect
expect-5.45-14.el7_1.x86_64
  • Execute script
[root@localhost ~]# sh disk.sh /dev/sdb$1
spawn fdisk /dev/sdb
欢迎使用 fdisk (util-linux 2.23.2)。

更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。

Device does not contain a recognized partition table
使用磁盘标识符 0x1f0887af 创建新的 DOS 磁盘标签。

命令(输入 m 获取帮助):n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): 
Using default response p
分区号 (1-4,默认 1):
起始 扇区 (2048-41943039,默认为 2048):
将使用默认值 2048
Last 扇区, +扇区 or +size{
    
    K,M,G} (2048-41943039,默认为 41943039):
将使用默认值 41943039
分区 1 已设置为 Linux 类型,大小设为 20 GiB

命令(输入 m 获取帮助):w
The partition table has been altered!

Calling ioctl() to re-read partition table.
正在同步磁盘。
Warning: 无法以读写方式打开 /dev/sr0 (只读文件系统)。/dev/sr0 已按照只读方式打开。
 磁盘格式化完成 
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda2        20G  3.8G   17G   19% /
devtmpfs        1.9G     0  1.9G    0% /dev
tmpfs           1.9G     0  1.9G    0% /dev/shm
tmpfs           1.9G  9.0M  1.9G    1% /run
tmpfs           1.9G     0  1.9G    0% /sys/fs/cgroup
/dev/sr0        4.3G  4.3G     0  100% /mnt
/dev/sda1       6.0G  174M  5.9G    3% /boot
/dev/sda3        10G   37M   10G    1% /home
tmpfs           378M  8.0K  378M    1% /run/user/42
tmpfs           378M     0  378M    0% /run/user/0
/dev/sdb         20G   33M   20G    1% /dev/sdb.1

Guess you like

Origin blog.csdn.net/weixin_51486343/article/details/111826792