Shell脚本(六)


学会了输出,那么输出什么呢?当然是人类让计算机运算的数据,那么运算的数据来自哪里?

可以肯定是你或其他人给的,那如何给程序数据呢?

那么我们就得看看如何实现人机交互了。

  • 比如计算机程序
  • 比如信息录入系统

一、read命令

功能:默认接受键盘的输入,回车符代表输入结束 应用场景:人机交互 命令选项

-p打印信息
-t限定时间
-s不回显
-n输入字符个数

二、交互输入案例

案例需求: 写一个系统用户交互登录界面脚本,仿linux文本界面登录 案例要点: 了解linux文本界面登陆所需要的输出信息及界面布局

job实现步骤: 1、根据linux文本界面登陆窗口输出信息,打印登陆提示信息 2、交互输入登陆账号 3、交互输入登陆密码

代码实现:

#job实现代码   02_login.sh
#!/bin/bash
# 
#Author: www.zuolaoshi.cn
#Release: 
#Description: 仿真登陆

IP=`ifconfig ens33|egrep -w "inet"|awk '{print $2}'`

#1、清屏
clear
#2、输出提示信息
echo "CentOS Linux 8 (Core)"
echo -e "Kernel `uname -r` on an `uname -m`\n"

echo -e "Web console: https://localhost:9090/ or https://$IP:9090/ \n"

#3、交互输入登陆名
echo -n "$HOSTNAME login: "
read account

#4、交互输入密码
read -s -t30 -p "Password: " pw
echo

一、案例应用场景

生产环境中的服务器一般会分为系统盘和数据盘两种磁盘,以dell R730举例,该服务器是一个2U的机架式服务器,满载可以挂载14块磁盘[2块在机箱内做系统盘,12块在面板做数据盘],我们一般的策略是系统盘做raid1,保障系统稳定性12块数据磁盘我们做raid10 或者 raid50,保障数据盘容错的同时还能做到优化IO的效果。

raid磁盘的容量是一定的,线上的数据又是不断增长的,也就是说总有一天会把你的数据磁盘填满,那怎么办?为了解决这个问题,人们想到了LVM[逻辑卷管理系统],当前数据盘容量不够用的时候,我们可以通过san存储获得网络磁盘,然后将该网络存储动态加入LVM中的卷组后就可以扩大LV了。整个过程采用在线扩容的方式,不会影响线上业务正是基于这个原因,我们又在系统中把raid数据盘在存数据之前做成了LVM磁盘,方便后续的扩容。

注意:有数据的磁盘不能再做LVM,因为需要格式化,数据会全部丢失。必须提前布局,否则就得提前准备跑路资金了。

二、案例需求

给虚拟机添加一块磁盘(以sdb为例),要求使用脚本对该磁盘分三个区:

 1)主分区 /dev/sdb3 543M 文件系统 ext4 要求开机自动挂载到/data/data1目录

 2) 逻辑分区 /dev/sdb5 2G

 3) 逻辑分区 /dev/sdb6 3G

使用/dev/sdb5 /dev/sdb6 新建卷组vg100,并创建一个PE为16M,容量为2.5G的逻辑卷lv100,
格式化为xfs,默认开机自动挂载到/data/data2目录

三、案例算法

算法:完成一个任务的代码思路。

脚本思路---算法
1、分区
2、创建逻辑卷
    2.1  创建物理卷
    2.2  创建卷组
    2.3  创建逻辑卷
3、格式化 /dev/sdb3   /dev/vg100/lv100
4、修改/etc/fstab文件
5、挂载分区
6、验证并输出挂载结果

四、代码实现

代码实现的要点:要清楚每一步的步骤,不同的系统可能有细微的差别,一味的复制可不行的,需要提前手动做一下,把步骤捋清楚。

实验代码    01_disk_partition.sh
#!/bin/bash
# 
#Author: Bai Shuming
#Created Time: 2019/11/1 21:05
#Release: 
#Description:
#
#给虚拟机添加一块磁盘(以sdb为例),要求使用脚本对该磁盘分三个区:
#  1)主分区 /dev/sdb3   543M   文件系统 ext4  要求开机自动挂载到/data/data1目录
#  2)   逻辑分区  /dev/sdb5   2G
#  3)   逻辑分区  /dev/sdb6   3G
#使用/dev/sdb5   /dev/sdb6   新建卷组vg100,并创建一个PE为16M,容量为2.5G的逻辑卷lv100,
#格式化为xfs,默认开机自动挂载到/data/data2目录

#1、分区
fdisk /dev/sdb <<EOF
n
p
3

+543M
n
e
4


n

+2G
n

+3G
w
EOF

#2、创建逻辑卷
   #2.1 创建物理卷
    pvcreate /dev/sdb5 /dev/sdb6
   #2.2 创建卷组
    vgcreate -s 16M vg100 /dev/sdb{5..6}
   #2.3 创建逻辑卷
    lvcreate -L 2.5G -n lv100 vg100
#3、格式化
mkfs.ext4 /dev/sdb3
mkfs.xfs /dev/vg100/lv100

#4、修改/etc/fstab,实现自动挂载
echo  "/dev/sdb3   /data/data1 ext4  defaults   0 0" >> /etc/fstab
echo "/dev/vg100/lv100 /data/data2  xfs   defaults 0 0" >> /etc/fstab

#5、挂载分区
mkdir -p /data/data{1..2}
mount -a

#6、验证并输出挂载结果
mount |grep "/dev/sdb3"
test $? -eq 0&&echo "/dev/sdb3 挂载成功" || echo "/dev/sdb3挂载失败"

##注意检索的时候,mount输出中LV的表示方式,或者直接检索挂载点/data/data2也可以。
mount |grep "vg100-lv100"
test $? -eq 0&&echo "/dev/vg100/lv100 挂载成功" || echo "/dev/vg100/lv100挂载失败"

五、实现验证

使用如下命令查看是否挂载成功
[root@zuolaoshi ~]# df -Th

六、expect

expect 是一个非常强大的自动化工具,尤其是当你需要与交互式程序进行交互(例如登录到远程服务器、输入密码、确认提示等)时。expect 可以模拟用户的键盘输入,从而实现自动化。

基本概念

  • spawn:启动一个新的进程或命令。
  • expect:等待特定的输出或提示。
  • send:向进程发送字符串。
  • interact:让用户接管交互。
  • expect eof:等待子进程结束。

基本语法

#!/usr/bin/expect

spawn <command>  # 启动命令
expect "<pattern>" { send "<response>\r" }  # 等待模式并发送响应
expect eof  # 等待命令结束

示例

示例 1:自动登录远程服务器

#!/usr/bin/expect

set timeout 20  # 设置超时时间
spawn ssh user@example.com
expect "password: " { send "your_password\r" }
expect "$ "  # 等待命令提示符例如 $  #)
send "ls -l\r"  # 发送命令
expect "$ "  # 等待命令提示符
send "exit\r"  # 发送退出命令
expect eof  # 等待命令结束

示例 2:自动安装软件包

#!/usr/bin/expect

spawn sudo apt-get install package_name
expect "\[Y/n\]" { send "Y\r" }
expect "Do you want to continue?" { send "Y\r" }
expect eof

示例 3:自动 FTP 上传文件

#!/usr/bin/expect

set timeout 20
spawn ftp ftp.example.com
expect "Name .*:" { send "username\r" }
expect "Password:" { send "your_password\r" }
expect "ftp> " { send "put /local/path/file.txt /remote/path/file.txt\r" }
expect "ftp> " { send "quit\r" }
expect eof

高级用法

变量和循环

#!/usr/bin/expect

set file_list [list "file1.txt" "file2.txt" "file3.txt"]
foreach file $file_list {
    spawn scp $file user@example.com:/remote/path
    expect "password: " { send "your_password\r" }
    expect "$ "
}
expect eof

处理多个 expect 模式

#!/usr/bin/expect

spawn command
expect {
    "pattern1" { send "response1\r" }
    "pattern2" { send "response2\r" }
    timeout { send_user "Timed out waiting for pattern\n"; exit 1 }
}
expect eof

常用命令

  • send_user:向用户发送消息(通常用于调试)。
  • set timeout:设置 expect 的超时时间。
  • exp_internal 1:启用调试模式,显示详细的交互过程。
  • interact:让用户接管交互,通常用于需要在某个点手动操作的场景。

总结

expect 是一个非常强大的自动化工具,适用于需要与对话式程序进行交互的场景。通过合理利用 spawnexpectsend 等命令,可以实现复杂任务的自动化。如果你有特定的自动化需求,可以进一步探索和使用 expect 脚本来实现。