zl程序教程

您现在的位置是:首页 >  工具

当前栏目

shell脚本应用(一)下

应用shell 脚本
2023-09-14 09:15:48 时间

目录

设置变量的作用范围

数值变量的运算

特殊的shell变量

环境变量

位置变量

预定义变量

shell脚本与计划任务

确定备份方案

编写MySQL备份脚本

设置计划任务


4)read命令

        除了上述赋值操作以外,还可以使用Bash的内置命令read来给变量赋值。read命令用来提示用户输入信息,从而实现简单的交互过程。执行时将从标准输入设备(键盘)输入一行内容,并以空格为分隔符,将读入的各字段以此赋值给指定的变量(多余的内容赋值给最后一个变量)。若指定的变量只有一个,则将整行内容赋值给此变量。

        例如,执行以下操作将会等待用户输入文字,并将输入的内容赋值给变量ToDir1。

 [root@mysql ~]# read ToDir1
 123
 [root@mysql ~]# echo $ToDir1 
 123

        为了使交互式操作的界面更加友好,提高易用性,read命令可以结合”-p“选项来设置提示信息,以便告知用户应该输入什么内容等相关事项。例如,若希望提示用户输入备份文件的存放目录,并将输入的路径信息赋值给变量ToDir2,可以执行以下操作。

 [root@mysql ~]# read -p "请指定备份存放目录:" ToDir2
 请指定备份存放目录:/opt/backup
 [root@mysql ~]# echo $ToDir2 
 /opt/backup
  • 设置变量的作用范围

        默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量。当进入子程序或新的子shell环境时,局部变量将无法使用。例如,直接执行Bash进入一个新的子shell脚本后,将无法引用父级shell环境中定义的product,version等变量。

 [root@mysql ~]# echo "$product $version"        //查看当前定义的变量值
 python 2.7.13
 [root@mysql ~]# bash                            //进入子shell环境
 [root@mysql ~]# echo "$product $version"        //无法调用父shell环境中的变量
  
 [root@mysql ~]# exit                            //返回原有的shell环境
 exit

        为了使用户定义的变量在所有的子shell环境中能够继续使用,减少重复设置工作,可以通过内部命令export将指定的变量导出为全局变量。用户可以同时指定多个变量名称作为参数(无需使用“$”符号),变量名之间以空格分隔。

 [root@mysql ~]# echo "product $version"                     //查看当前定义的变量
 product 2.7.13
 [root@mysql ~]# export product version                      //设置为全局变量
 [root@mysql ~]# bash                                        //进入子shell环境
 [root@mysql ~]# echo "$product $version"                    //可以调用父shell的全局变量
 python 2.7.13
 [root@mysql ~]# exit                                        //返回原有的shell环境
 exit

        使用export导出全局变量的同时,也可以为变量进行赋值,这样在新定义全局变量时就不需要提前进行赋值了。执行以下操作可以直接新建一个名为AAA的全局变量。

 [root@mysql ~]# export AAA="www.123.com.cn"
 [root@mysql ~]# echo $AAA
 www.123.com.cn
  • 数值变量的运算

        shell变量的数值运算多用于脚本程序的过程控制(如循环次数,使用量比较等),在Bash Shell环境中,只进行简单的整数运算,不支持小数运算。整数的运算主要通过内部命令expr进行,基本格式如下所示。需要注意,运算符与变量之间必须有至少一个空格。

 expr  变量1   运算符  变量2  [运算符  变量3] ...

其中变量1,变量2......对应为需要计算的数值变量(需要以“$“符号调用),常用的几种运算符如下。

 加法运算:+
 减法运算: -
 乘法运算: \*
 除法运算: /
 求模(取余)运算: % (用来计算数值相除后的余数)


以下操作设置了x为35,y为16两个变量,并依次演示了变量x,y的加,减,乘,除,取模运算结果

 [root@mysql ~]# x=35
 [root@mysql ~]# y=16
 [root@mysql ~]# expr $x + $y
 51
 [root@mysql ~]# expr $x - $y
 19
 [root@mysql ~]# expr $x \* $y
 560
 [root@mysql ~]# expr $x / $y
 2
 [root@mysql ~]# expr $x % $y
 3

        若要将运算结果赋值给其他变量,可以结合命令替换操作(使用反撇号)。例如,计算变量y的3次方,并将结果赋值给变量Ycube。

 [root@mysql ~]# Ycube=`expr $y \* $y \* $y`
 [root@mysql ~]# echo $Ycube 
 4096

特殊的shell变量

        除了用户自行定义的shell变量以外,在Linux系统和Bash shell环境中还有一系列的特殊变量——环境变量,位置变量,预定义变量。

  • 环境变量

        环境变量指的是处于运行需要而由Linux系统提前创建的一类变量,主要用于设置用户的工作环境,包括用户宿主目录,命令查找路径,用户当前目录,登录终端等。环境变量的值由Linux系统自动维护,会随着用户状态的改变而改变。

        使用env命令可以查看到当前工作环境下的环境变量,对于常见的一些环境变量应了解其各自的用途。例如,变量USER表示用户名称,HOME表示用户的宿主目录,LANG表示语言和字符集,PWD表示当前所在的工作目录,PATH表示命令搜索路径等。

 [root@mysql ~]# env
 XDG_SESSION_ID=7
 HOSTNAME=mysql
 version=2.7.13
 TERM=xterm
 SHELL=/bin/bash
 HISTSIZE=1000
 SSH_CLIENT=192.168.10.10 51603 22
 SSH_TTY=/dev/pts/2
 USER=root
 ... //省略部分内容

        PATH变量用于设置可执行程序的默认搜索路径,当仅指定文件名成来执行命令程序时,linux系统静载PATH变量指定的目录范围查找对应的可执行文件,如果找不到则会提示“command not found”。例如,first.sh脚本位于/root目录下,若希望能够直接通过文件名称来运行脚本,可以修改PATH变量以添加搜索路径,或者将first.sh脚本复制到现有搜索路径中的某个文件夹下。

 [root@mysql ~]# ls -lh /root/first.sh                       //确认脚本位置
 -rwxr-xr-x 1 root root 142 May 25 12:33 /root/first.sh
 [root@mysql ~]# echo $PATH                                  //查看当前搜索路径
 /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/usr/local/mysql/bin:/root/bin
 [root@mysql ~]# first.sh                                    //直接执行时找不到命令
 bash: first.sh: command not found...
 [root@mysql ~]# PATH="$PATH:/root"                          //将/root添加到搜索路径
 [root@mysql ~]# echo $PATH                                  //查看修改后的搜索路径
 /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/usr/local/mysql/bin:/root/bin:/root
 [root@mysql ~]# first.sh                                    //直接以文件名运行脚本
 当前的目录位于:
 /boot
 其中以VM1开头的文件包括:
 -rwxr-xr-x. 1 root root 5.2M May 11  2018 vmlinuz-0-rescue-a51a41794fd84bc580413505b391c
 -rwxr-xr-x. 1 root root 5.2M Nov 23  2016 vmlinuz-3.10.0-514.el7.x86_64

        在Linux系统中,环境变量的全局配置文件为/etc/profile,再此文件中定义的变量作用于所有的用户。除此之外,每个用户还有自己的独立配置文件(~/.bash_profile)。若要长期变更或设置某个环境变量,应在上述文件中进行设置。例如,执行以下操作可以将记录的历史命令条数改为200条(默认为1000条),只针对root用户。

 [root@mysql ~]# vim /root/.bash_profile
 //   ...省略部分内容
 export HISTSIZE=200                     //添加,设置为200条
 [root@mysql ~]# history | wc -l
 360
 [root@mysql ~]# source /root/.bash_profile 
 [root@mysql ~]# history | wc -l
 200
  • 位置变量

        为了在使用shell脚本程序时,方便通过命令行为程序提供操作参数,Bash引入了位置变量的概念。当执行命令行操作时,第一个字段表示命令名或者脚本程序名,其余的字符串参数按照从左到右的顺序以此赋值给位置变量。

        位置变量也称为位置参数,使用$1,$2,$3,...$9表示。例如,当执行命令行“ls -lh /boot”时,其中第一个位置变量为“-lh”,以“$1”表示;第二个位置变量为“/boot”,以“$2”表示。命令或脚本本身的名称使用“$0”表示,虽然$0与位置变量的格式相同,但是$0属于预定义变量而不是位置变量。

        为了说明位置变量的作用,下面编写一个加法运算的小脚本adder2num.sh,用来计算两个整数的和。需要计算的两个整数在执行脚本时以位置变量的形式提供。

 [root@mysql ~]# vim /adder2num.sh
 #!/bin/bash
 SUM=`expr $1 + $2`
 echo "$1 + $2 = $SUM"
 [root@mysql ~]# chmod +x adder2num.sh 
 [root@mysql ~]# ./adder2num.sh 12 34
 12 + 34 = 46
 [root@mysql ~]# ./adder2num.sh 56 78
 56 + 78 = 134
  • 预定义变量

        预定义变量是由Bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,而不能直接为预定义变量赋值。预定义变量使用“$”符号和另一个符号组合表示,比较常用的几个预定义变量含义如下。

 预定义变量
 $#:命令行中位置变量的个数
 $*:所有位置变量的内容
 $?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
 $0:当前执行的进程/程序名

        为了说明预定义变量的作用,下面编写一个备份操作的小脚本,用来打包命令行指定的多个文件或目录,并输出相关信息。其中,新建的压缩包文件名称中嵌入秒刻(从1970年1月1日至今经过的秒数),通过“date +%s”命令获取秒刻时间。

 [root@mysql ~]# vim mybak.sh
 ​
 #!/bin/bash
 TARFILE=beifen-`date +%s`.tgz
 tar zcf $TARFILE $* &> /dev/null
 echo "已执行 $0 脚本,"
 echo "共完成$#个对象的备份"
 echo "具体内容包括:$*"
 [root@mysql ~]# chmod +x mybak.sh
 [root@mysql ~]# ./mybak.sh /boot/grub
 已执行 ./mybak.sh 脚本,
 共完成1个对象的备份
 具体内容包括:/boot/grub
 [root@mysql ~]# ./mybak.sh /etc/passwd /etc/shadow
 已执行 ./mybak.sh 脚本,
 共完成2个对象的备份
 具体内容包括:/etc/passwd /etc/shadow
 [root@mysql ~]# ls -lh beifen-*
 -rw-r--r-- 1 root root  367 May 25 13:43 beifen-1653457418.tgz
 -rw-r--r-- 1 root root 1.5K May 25 13:43 beifen-1653457439.tgz

shell脚本与计划任务

        周期性的任务可以通过Crond服务来管理,而步骤复杂,操作繁琐的任务可以使用shell脚本来批量处理,两者相结合就可以非常灵活,自主地完成各种系统运维工作。

  • 确定备份方案

        对于存在多个应用的数据库服务器,备份工作可能会划分得比较详细,需要针对不同的数据库和表不同的备份路径使用不同的验证用户等。

        一共两台MySQL服务器A和B,在B上远程备份A上的数据库,在A上建立数据库benet和accp,两台主机关闭防火墙。客户端A为10.100客户端B为10.200.

(1)在客户端Ashang创建两个数据库,分别为benet和accp

 mysql> create database benet;
 Query OK, 1 row affected (0.00 sec)
 ​
 mysql> create database accp;
 Query OK, 1 row affected (0.00 sec)

(2)在服务器端A上建立一个专用的数据库用户,本实验用的是root用户,授权root账户可以通过远程主机192.168.10.200连接A

 mysql> grant all on *.* to 'root'@'192.168.10.200' identified by '123456';
 Query OK, 0 rows affected (0.00 sec)

(3)在备份主机B上测试,查看是否备份成功

 [root@mysql ~]#  mysqldump -uroot -p123456 -h 192.168.10.100 --databases benet > benet.sql
 Warning: Using a password on the command line interface can be insecure.
 [root@mysql ~]# ls -lh benet.sql
 -rw-r--r-- 1 root root 1.4K May 25 15:05 benet.sql
  • 编写MySQL备份脚本

(1)在备份主机B上编写脚本,之前需要先创建备份目录/opt/beifen,然后编写脚本。

 [root@mysql ~]# mkdir -p /opt/beifen
 [root@mysql ~]# vim mysqlbak.sh
 #!/bin/bash
 my_user="root"
 my_pass="123456"
 my_host="192.168.10.100"
 my_conn="-u $my_user -p$my_pass -h $my_host"
 my_db1="benet"
 my_db2="accp"
 bf_dir="/opt/beifen"
 bf_cmd="/usr/local/mysql/bin/mysqldump"
 bf_time=`date +%Y%m%d-%H%M`
 name_1="$my_db1-$bf_time"
 name_2="$my_db2-$bf_time"
 cd $bf_dir
 $bf_cmd $my_conn --databases $my_db1 > $name.1.sql
 $bf_cmd $my_conn --databases $my_db2 > $name.2.sql
 /bin/tar czf $name_1.tar.gz $name_1.sql --remove &> /dev/null
 /bin/tar czf $name_2.tar.gz $name_2.sql --remove &> /dev/null

(2)设置x权限,并执行脚本

 [root@mysql ~]# chmod +x mysqlbak.sh 
 [root@mysql ~]# ./mysqlbak.sh 
 Warning: Using a password on the command line interface can be insecure.
 Warning: Using a password on the command line interface can be insecure.

(3)查看结果

 [root@mysql ~]# ls -lh /opt/beifen
 total 8.0K
 -rw-r--r-- 1 root root 45 May 25 15:27 accp-20220525-1527.tar.gz
 -rw-r--r-- 1 root root 45 May 25 15:27 benet-20220525-1527.tar.gz
 
  • 设置计划任务

设置每天晚上22:00自动备份

 [root@mysql ~]# mv mysqlbak.sh /opt/beifen
 [root@mysql ~]# crontab -e
 no crontab for root - using an empty one
 crontab: installing new crontab
 00 22 * * * /opt/beifen/mysqlbak.sh

可以修改时间为21:59分,查看是否自动备份

 [root@mysql ~]# date -s 21:59:50
 [root@mysql ~]# ls -lh /opt/beifen
 total 20K
 -rw-r--r-- 1 root root  45 May 25 15:27 accp-20220525-1527.tar.gz
 -rw-r--r-- 1 root root  45 May 26 22:00 accp-20220526-2200.tar.gz
 -rw-r--r-- 1 root root  45 May 25 15:27 benet-20220525-1527.tar.gz
 -rw-r--r-- 1 root root  45 May 26 22:00 benet-20220526-2200.tar.gz
 -rwxr-xr-x 1 root root 522 May 25 15:25 mysqlbak.sh