4)read命令
除了上述赋值操作以外,还可以使用Bash的内置命令read来给变量赋值。read命令用来提示用户输入信息,从而实现简单的交互过程。执行时将从标准输入设备(键盘)输入一行内容,并以空格为分隔符,将读入的各字段以此赋值给指定的变量(多余的内容赋值给最后一个变量)。若指定的变量只有一个,则将整行内容赋值给此变量。
例如,执行以下操作将会等待用户输入文字,并将输入的内容赋值给变量ToDir1。
1. [root@mysql ~]# read ToDir1 2. 123 3. [root@mysql ~]# echo $ToDir1 4. 123
为了使交互式操作的界面更加友好,提高易用性,read命令可以结合”-p“选项来设置提示信息,以便告知用户应该输入什么内容等相关事项。例如,若希望提示用户输入备份文件的存放目录,并将输入的路径信息赋值给变量ToDir2,可以执行以下操作。
1. [root@mysql ~]# read -p "请指定备份存放目录:" ToDir2 2. 请指定备份存放目录:/opt/backup 3. [root@mysql ~]# echo $ToDir2 4. /opt/backup
默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量。当进入子程序或新的子shell环境时,局部变量将无法使用。例如,直接执行Bash进入一个新的子shell脚本后,将无法引用父级shell环境中定义的product,version等变量。
1. [root@mysql ~]# echo "$product $version" //查看当前定义的变量值 2. python 2.7.13 3. [root@mysql ~]# bash //进入子shell环境 4. [root@mysql ~]# echo "$product $version" //无法调用父shell环境中的变量 5. 6. [root@mysql ~]# exit //返回原有的shell环境 7. exit
为了使用户定义的变量在所有的子shell环境中能够继续使用,减少重复设置工作,可以通过内部命令export将指定的变量导出为全局变量。用户可以同时指定多个变量名称作为参数(无需使用“$”符号),变量名之间以空格分隔。
1. [root@mysql ~]# echo "product $version" //查看当前定义的变量 2. product 2.7.13 3. [root@mysql ~]# export product version //设置为全局变量 4. [root@mysql ~]# bash //进入子shell环境 5. [root@mysql ~]# echo "$product $version" //可以调用父shell的全局变量 6. python 2.7.13 7. [root@mysql ~]# exit //返回原有的shell环境 8. exit
使用export导出全局变量的同时,也可以为变量进行赋值,这样在新定义全局变量时就不需要提前进行赋值了。执行以下操作可以直接新建一个名为AAA的全局变量。
1. [root@mysql ~]# export AAA="www.123.com.cn" 2. [root@mysql ~]# echo $AAA 3. www.123.com.cn
shell变量的数值运算多用于脚本程序的过程控制(如循环次数,使用量比较等),在Bash Shell环境中,只进行简单的整数运算,不支持小数运算。整数的运算主要通过内部命令expr进行,基本格式如下所示。需要注意,运算符与变量之间必须有至少一个空格。
expr 变量1 运算符 变量2 [运算符 变量3] ...
其中变量1,变量2......对应为需要计算的数值变量(需要以“$“符号调用),常用的几种运算符如下。
1. 加法运算:+ 2. 减法运算: - 3. 乘法运算: \* 4. 除法运算: / 5. 求模(取余)运算: % (用来计算数值相除后的余数)
以下操作设置了x为35,y为16两个变量,并依次演示了变量x,y的加,减,乘,除,取模运算结果
1. [root@mysql ~]# x=35 2. [root@mysql ~]# y=16 3. [root@mysql ~]# expr $x + $y 4. 51 5. [root@mysql ~]# expr $x - $y 6. 19 7. [root@mysql ~]# expr $x \* $y 8. 560 9. [root@mysql ~]# expr $x / $y 10. 2 11. [root@mysql ~]# expr $x % $y 12. 3
若要将运算结果赋值给其他变量,可以结合命令替换操作(使用反撇号)。例如,计算变量y的3次方,并将结果赋值给变量Ycube。
1. [root@mysql ~]# Ycube=`expr $y \* $y \* $y` 2. [root@mysql ~]# echo $Ycube 3. 4096
特殊的shell变量
除了用户自行定义的shell变量以外,在Linux系统和Bash shell环境中还有一系列的特殊变量——环境变量,位置变量,预定义变量。
环境变量指的是处于运行需要而由Linux系统提前创建的一类变量,主要用于设置用户的工作环境,包括用户宿主目录,命令查找路径,用户当前目录,登录终端等。环境变量的值由Linux系统自动维护,会随着用户状态的改变而改变。
使用env命令可以查看到当前工作环境下的环境变量,对于常见的一些环境变量应了解其各自的用途。例如,变量USER表示用户名称,HOME表示用户的宿主目录,LANG表示语言和字符集,PWD表示当前所在的工作目录,PATH表示命令搜索路径等。
1. [root@mysql ~]# env 2. XDG_SESSION_ID=7 3. HOSTNAME=mysql 4. version=2.7.13 5. TERM=xterm 6. SHELL=/bin/bash 7. HISTSIZE=1000 8. SSH_CLIENT=192.168.10.10 51603 22 9. SSH_TTY=/dev/pts/2 10. USER=root 11. ... //省略部分内容
PATH变量用于设置可执行程序的默认搜索路径,当仅指定文件名成来执行命令程序时,linux系统静载PATH变量指定的目录范围查找对应的可执行文件,如果找不到则会提示“command not found”。例如,first.sh脚本位于/root目录下,若希望能够直接通过文件名称来运行脚本,可以修改PATH变量以添加搜索路径,或者将first.sh脚本复制到现有搜索路径中的某个文件夹下。
1. [root@mysql ~]# ls -lh /root/first.sh //确认脚本位置 2. -rwxr-xr-x 1 root root 142 May 25 12:33 /root/first.sh 3. [root@mysql ~]# echo $PATH //查看当前搜索路径 4. /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/usr/local/mysql/bin:/root/bin 5. [root@mysql ~]# first.sh //直接执行时找不到命令 6. bash: first.sh: command not found... 7. [root@mysql ~]# PATH="$PATH:/root" //将/root添加到搜索路径 8. [root@mysql ~]# echo $PATH //查看修改后的搜索路径 9. /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/usr/local/mysql/bin:/root/bin:/root 10. [root@mysql ~]# first.sh //直接以文件名运行脚本 11. 当前的目录位于: 12. /boot 13. 其中以VM1开头的文件包括: 14. -rwxr-xr-x. 1 root root 5.2M May 11 2018 vmlinuz-0-rescue-a51a41794fd84bc580413505b391c 15. -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用户。
1. [root@mysql ~]# vim /root/.bash_profile 2. // ...省略部分内容 3. export HISTSIZE=200 //添加,设置为200条 4. [root@mysql ~]# history | wc -l 5. 360 6. [root@mysql ~]# source /root/.bash_profile 7. [root@mysql ~]# history | wc -l 8. 200
为了在使用shell脚本程序时,方便通过命令行为程序提供操作参数,Bash引入了位置变量的概念。当执行命令行操作时,第一个字段表示命令名或者脚本程序名,其余的字符串参数按照从左到右的顺序以此赋值给位置变量。
位置变量也称为位置参数,使用$1,$2,$3,...$9表示。例如,当执行命令行“ls -lh /boot”时,其中第一个位置变量为“-lh”,以“$1”表示;第二个位置变量为“/boot”,以“$2”表示。命令或脚本本身的名称使用“$0”表示,虽然$0与位置变量的格式相同,但是$0属于预定义变量而不是位置变量。
为了说明位置变量的作用,下面编写一个加法运算的小脚本adder2num.sh,用来计算两个整数的和。需要计算的两个整数在执行脚本时以位置变量的形式提供。
1. [root@mysql ~]# vim /adder2num.sh 2. #!/bin/bash 3. SUM=`expr $1 + $2` 4. echo "$1 + $2 = $SUM" 5. [root@mysql ~]# chmod +x adder2num.sh 6. [root@mysql ~]# ./adder2num.sh 12 34 7. 12 + 34 = 46 8. [root@mysql ~]# ./adder2num.sh 56 78 9. 56 + 78 = 134
预定义变量是由Bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,而不能直接为预定义变量赋值。预定义变量使用“$”符号和另一个符号组合表示,比较常用的几个预定义变量含义如下。
1. 预定义变量 2. $#:命令行中位置变量的个数 3. $*:所有位置变量的内容 4. $?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错 5. $0:当前执行的进程/程序名
为了说明预定义变量的作用,下面编写一个备份操作的小脚本,用来打包命令行指定的多个文件或目录,并输出相关信息。其中,新建的压缩包文件名称中嵌入秒刻(从1970年1月1日至今经过的秒数),通过“date +%s”命令获取秒刻时间。
1. [root@mysql ~]# vim mybak.sh 2. 3. #!/bin/bash 4. TARFILE=beifen-`date +%s`.tgz 5. tar zcf $TARFILE $* &> /dev/null 6. echo "已执行 $0 脚本," 7. echo "共完成$#个对象的备份" 8. echo "具体内容包括:$*" 9. [root@mysql ~]# chmod +x mybak.sh 10. [root@mysql ~]# ./mybak.sh /boot/grub 11. 已执行 ./mybak.sh 脚本, 12. 共完成1个对象的备份 13. 具体内容包括:/boot/grub 14. [root@mysql ~]# ./mybak.sh /etc/passwd /etc/shadow 15. 已执行 ./mybak.sh 脚本, 16. 共完成2个对象的备份 17. 具体内容包括:/etc/passwd /etc/shadow 18. [root@mysql ~]# ls -lh beifen-* 19. -rw-r--r-- 1 root root 367 May 25 13:43 beifen-1653457418.tgz 20. -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
1. mysql> create database benet; 2. Query OK, 1 row affected (0.00 sec) 3. 4. mysql> create database accp; 5. Query OK, 1 row affected (0.00 sec)
(2)在服务器端A上建立一个专用的数据库用户,本实验用的是root用户,授权root账户可以通过远程主机192.168.10.200连接A
1. mysql> grant all on *.* to 'root'@'192.168.10.200' identified by '123456'; 2. Query OK, 0 rows affected (0.00 sec)
(3)在备份主机B上测试,查看是否备份成功
1. [root@mysql ~]# mysqldump -uroot -p123456 -h 192.168.10.100 --databases benet > benet.sql 2. Warning: Using a password on the command line interface can be insecure. 3. [root@mysql ~]# ls -lh benet.sql 4. -rw-r--r-- 1 root root 1.4K May 25 15:05 benet.sql
- 编写MySQL备份脚本
(1)在备份主机B上编写脚本,之前需要先创建备份目录/opt/beifen,然后编写脚本。
1. [root@mysql ~]# mkdir -p /opt/beifen 2. [root@mysql ~]# vim mysqlbak.sh 3. #!/bin/bash 4. my_user="root" 5. my_pass="123456" 6. my_host="192.168.10.100" 7. my_conn="-u $my_user -p$my_pass -h $my_host" 8. my_db1="benet" 9. my_db2="accp" 10. bf_dir="/opt/beifen" 11. bf_cmd="/usr/local/mysql/bin/mysqldump" 12. bf_time=`date +%Y%m%d-%H%M` 13. name_1="$my_db1-$bf_time" 14. name_2="$my_db2-$bf_time" 15. cd $bf_dir 16. $bf_cmd $my_conn --databases $my_db1 > $name.1.sql 17. $bf_cmd $my_conn --databases $my_db2 > $name.2.sql 18. /bin/tar czf $name_1.tar.gz $name_1.sql --remove &> /dev/null 19. /bin/tar czf $name_2.tar.gz $name_2.sql --remove &> /dev/null
(2)设置x权限,并执行脚本
1. [root@mysql ~]# chmod +x mysqlbak.sh 2. [root@mysql ~]# ./mysqlbak.sh 3. Warning: Using a password on the command line interface can be insecure. 4. Warning: Using a password on the command line interface can be insecure.
(3)查看结果
1. [root@mysql ~]# ls -lh /opt/beifen 2. total 8.0K 3. -rw-r--r-- 1 root root 45 May 25 15:27 accp-20220525-1527.tar.gz 4. -rw-r--r-- 1 root root 45 May 25 15:27 benet-20220525-1527.tar.gz 5.
设置每天晚上22:00自动备份
1. [root@mysql ~]# mv mysqlbak.sh /opt/beifen 2. [root@mysql ~]# crontab -e 3. no crontab for root - using an empty one 4. crontab: installing new crontab 5. 00 22 * * * /opt/beifen/mysqlbak.sh
可以修改时间为21:59分,查看是否自动备份
1. [root@mysql ~]# date -s 21:59:50 2. [root@mysql ~]# ls -lh /opt/beifen 3. total 20K 4. -rw-r--r-- 1 root root 45 May 25 15:27 accp-20220525-1527.tar.gz 5. -rw-r--r-- 1 root root 45 May 26 22:00 accp-20220526-2200.tar.gz 6. -rw-r--r-- 1 root root 45 May 25 15:27 benet-20220525-1527.tar.gz 7. -rw-r--r-- 1 root root 45 May 26 22:00 benet-20220526-2200.tar.gz 8. -rwxr-xr-x 1 root root 522 May 25 15:25 mysqlbak.sh