Linux学习 Shell编程
13 Shell编程
(1) 概述
Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。
(2) Shell脚本执行方式
<1> 格式要求
<1.1> 脚本以[#!/bin/bash]开头
<1.2> 单行注释 [#]
<1.3> shell 脚本的多行注释
//:<<!和!必须独占一行。
:<<!
内容
!
<2> 执行方式
<2.1> 输入脚本的绝对路径或相对路径
//首先要赋予脚本的+x权限,再执行脚本。
//当脚本在当前文件夹下时,在脚本前加./,比如[./hello.sh]。
<2.2> sh 脚本路径
//不用赋予脚本+x 权限,直接执行即可。
//sh也可以使用绝对路径
(3) Shell脚本变量
<1> 概述
<1.1> Linux Shell中的变量分为,系统变量和用户自定义变量。
<1.2> 系统变量:$HOME、$PWD、$SHELL、$USER 等等,比如:[echo $HOME]等等。
<1.3> 显示当前shell中所有变量 [set]
<2> 定义变量
<2.1> 定义变量 [变量名=值]
<2.2> 撤销变量 [unset 变量名]
<2.3> 声明静态变量 [readonly 变量名]
<2.4> 静态变量不能 [unset] 撤销
<3> 定义变量的规则
<3.1> 变量名称可以由字母、数字和下划线组成,但是不能以数字开头。
<3.2> 等号两侧不能有空格。
<3.3> 变量名称一般习惯为大写, 这是一个规范,我们遵守即可将命令的返回值赋给变量。
<3.4> [A=`date`] 代表,运行data命令,并把结果返回给变量A。//``反引号代表命令或变量
<3.5> [A=$(date)] 等价于反引号。
<4> 使用变量时,需要在变量前加上[${}],注明为是一个变量,否则会按照字符串处理。如[echo A=${变量名}]。
//${}是参数,{}是为了避免参数名称与后面的字符混淆,若不易混淆,可以省略。
//若使用''引起变量,即使加了$,仍会按照字符串处理。如:[echo '$A']仍输出$A。
//使用""引起变量,与不使用""效果相同。
<5> echo命令 单引号/双引号/不加引号的区别
不加引号:字符串原样输出,变量会被替换
单引号:引号里面的内容会原封不动的显示出来
双引号:里面的特殊符号会被解析,变量也会被替换
//双引号相较于不加引号功能更强大。
(4) 设置环境变量
<1> 基本语法
<1.1> 将shell变量输出为环境变量/全局变量 [export 变量名=变量值]
<1.2> 让修改后的配置信息立即生效 [source 配置文件]
<1.3> 查询环境变量的值 [echo $变量名]
<2> 快速入门
<2.1> 编辑环境变量的配置文件 [vim /etc/profile]
<2.2> 导入环境变量 [export 变量名=变量值]
<2.3> 让新的环境变量生效 [source /etc/profile]
<2.4> 查询环境变量的值 [echo $变量名]
(5) 位置参数变量
<1> 概述
当我们执行一个shell脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量。
<2> 基本语法
//执行shell脚本时传递参数 [sh 脚本路径 参数1 参数2 ...]
$n:n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}
$*:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体,相当于一个数据
$@:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待,相当于多个数据
$#:这个变量代表命令行中所有参数的个数
(6) 预定义变量
<1> 概述
shell设计者事先已经定义好的变量,可以直接在shell脚本中使用。
<2> 基本语法
$$:当前进程的进程号(PID)
$!:后台运行的最后一个进程的进程号(PID)
$?:最后一次执行的命令的返回状态
//如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0,则证明上一个命令执行不正确了。
(7) 运算符
<1> "$((运算式))"或"$[运算式]"或"expr m + n" //expression表达式
<2> 注意expr运算符间要有空格,如果希望将expr的结果赋给某个变量,使用``(反引号)
<3> \*(乘)、 /(除)、 %(取余)
(8) 条件判断
<1> 基本语法[ 条件判断式 ](注意条件前后要有空格)
//非空返回true,可使用$?验证(0为true,>1为false)
[ ! 条件判断式 ]条件的否定形式直接在[]内加!
<2> 常用判断条件
<2.1> 两个变量或常量进行比较 =
//例:[ A=B ]
<2.2> 两个整数的比较
//例:[ A 选项 B ]
-lt(less than):小于
-le(less equal):小于等于
-eq(equal):等于
-gt(greater than):大于
-ge(greater equal):大于等于
-ne(not equal):不等于
<2.3> 按照文件权限进行判断
//例:[ 选项 文件路径 ]
-r:有读的权限
-w:有写的权限
-x:有执行的权限
<2.4> 按照文件类型进行判断
//例:[ 选项 文件路径 ]
-f(file):文件存在并且是一个常规的文件
-e(exist):文件存在
-d(directionary):文件存在并是一个目录
(9) 流程控制
<1> if判断
//if和[有空格,条件判断式和[也有空格。
if [[ 条件判断式 ]]
then
代码
fi
或者
if [[ 条件判断式 ]]
then
代码
elif [[ 条件判断式 ]]
then
代码
fi
<2> case语句
case $变量名 in
"值1")
代码1
;;
"值2")
代码2
;;
...
*)
代码
;;
esac
<3> for循环
for 变量 in 值1 值2 值3…
do
代码
done
//i就是遍历值的容器,没有属于的意思。
或
//for和((有空格,条件和))也有空格。
for (( 初始值;循环控制条件;变量变化 ))
do
代码
done
//变量变化可以写i++,但代码中不可以写i++,只能写$[$i+1]
<4> while循环
//while和[有空格,条件判断式和[也有空格。
//break跳出循环 continue结束本次循环 exit退出脚本
while [[ 条件判断式 ]]
do
代码
done
(10) 控制台输入
[read -p 变量名]
//变量名接收读取输入的值,变量名前不用加$。
-p:指定读取值时的提示符
-t<时间>:指定读取值时等待的时间(秒)
(11) 函数
<1> 系统函数
<1.1> 返回完整路径最后/的部分,常用于获取文件名 [basename 前缀 后缀]
//后缀根据情况选择是否删除。
//basename命令会删掉所有的前缀包括最后一个(‘/’)字符,之后删掉后缀,然后将字符串显示出来。
<1.2> 返回完整路径最后/的前面的部分,常用于返回路径部分 [dirname 文件绝对路径]
//功能与basename相反。
//功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)。
<2> 自定义函数
function 函数名()
{
代码
}
//调用直接写函数名函数名 $参数1 $参数2 ...
(12) Shell编程综合案例
<1> 需求分析
<1.1> 每天凌晨 2:30 备份 数据库 db1 到 /data/backup/db1
<1.2> 备份开始和备份结束能够给出相应的提示信息
<1.3> 备份后的文件要求以备份时间为文件名,并打包成 .tar.gz 的形式,比如:2021-03-12_230201.tar.gz
<1.4> 在备份的同时,检查是否有 10 天前备份的数据库文件,如果有就将其删除。
<2> 代码实现
<2.1> 编写脚本
#!/bin/bash
#备份目录
BACKUP=/data/backup/db
#当前时间
DATETIME=$(date +%Y-%m-%d_%H%M%S)
echo $DATETIME
#数据库的地址
HOST=localhost
#数据库用户名
DB_USER=root
#数据库密码
DB_PW=1234
#备份的数据库名
DATABASE=db1
#创建备份目录, 如果备份目录不存在,就创建备份目录。
[ ! -d "${BACKUP}/${DATETIME}" ] && mkdir -p "${BACKUP}/${DATETIME}"
#先备份数据库,然后将数据库备份文件压缩为$DATETIME.sql.gz。
mysqldump -u${DB_USER} -p${DB_PW} --host=${HOST} -q -R --databases ${DATABASE} | gzip > ${BACKUP}/${DATETIME}/$DATETIME.sql.gz
//u(username):用户 p(password):密码 host:主机地址 q(quick):不会把SELECT出来的结果放在buffer中,使用mysqldump来备份数据时,建议总是加上-q参数。 R(recursive):递归 datebases:数据库名
#将数据库备份文件所在文件夹${DATETIME}处理成tar.gz
cd ${BACKUP}
tar -zcvf $DATETIME.tar.gz ${DATETIME}
#删除数据库备份文件所在的备份目录${DATETIME}
rm -rf ${BACKUP}/${DATETIME}
#删除10天前的备份文件
find ${BACKUP} -atime +10 -name "*.tar.gz" -exec rm -rf {} \;
echo "数据库${DATABASE}备份成功"
<2.2> 定时任务调度
给mysqlDump.sh增加执行权限 [chmod u+x /data/backup/db1/mysqlDump.sh]
定时执行脚本 [crontab -e]、[30 2 * * * /data/backup/db1/mysqlDump.sh]

浙公网安备 33010602011771号