Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。
# vim hello.sh 创建脚本,一般通过 .sh 表示是一个可执行脚本文件# BEGIN 模拟打开 vim#!/bin/bash# 上述开头,表明使用 哪种 shell# 内容# END# 编写完成后# # 方式一:添加执行权限 x,执行脚本# # 方式二:使用 sh 脚本 直接执行# 单行注释:<<!多行注释!
一、Shell 变量
Linux Shell 变量分为,系统变量和用户自定义变量。
1. 系统变量
$HOME $PATH $SHELL $USER
使用 set 指令可以查看
# 案例:环境变量 /etc/profileexport 变量名=变量值export JAVA_HOME:$PATHsource /etc/profileecho $JAVA_HOME
2. 自定义变量
#!/bin/bash# 定义变量的语法 变量名=值,切记不要有空格# 销毁变量,unset 变量名# 静态变量,readonly变量名,注意无法 unset# 案例1:定义变量AA=100# 输出A,需要引用:$A 或 ${A}echo $Aecho A=$A #不会被当作变量,原封输出echo "A=$A" #效果相同# 运行结果# 100# A=100# A=100# 案例2:撤销变量Aunset Aecho "A=$A"# 运行结果# A=# 案例3:声明静态Breadonly B=2echo "B=$B"# 如果 unset B,运行时出错
说明:
- 变量名:字母,数字,下划线组成,但数字不可打头
- 等号两侧不能有空格
- 变量名习惯为大写
# 4. `将反引号内容看作是命令,将结果返回给等号前的变量` 同理写法 $()A=`date`B=$(date)
3. 位置参数变量
当我们执行一个脚本的时候,希望获得命令中的参数值,使用位置参数变量 如:./myshell.sh 100 200,如何获取 100 200
# 基本语法$n:<<!n 表示数字$0 代表命令本身$1-$9 表示 1-9 参数${10} 表示 10 以上使用大括号!$*# 表示所有参数,将所有参数当作一个整体$@# 表示所有参数,将参数区分对待$## 表示参数的个数
4. 预定义变量
shell 设计者已经定义好的变量,可以在 shell 中直接使用
# 基本语法$$ # 当前进程的进程号 PID$! # 后台运行的最后一个进程的进程号 PID$? # 最后一次执行命令的返回状态,0表示成功,非0,不成功,具体根据指令# 案例#!bin/bashecho "当前执行的进程id=$$"# 以后台形式运行一个脚本,并获取进程号 &表示后台运行/root/shcode/myshell.sh &echo "最后一个后台方式运行的进程id=$!"echo "执行结果=$?"
二、运算符
# 基本语法$((运算式)) 或者 $[运算式] 或者 expr 运算式# 说明1:如果使用 expr 的形式,# 运算符需要在两侧添加空格 expr m + n,若写成 m+n 结果是输出 m+n# 结果需要 `expr m + n` 来获取# 乘法 \*,除法 /,取余 %
三、条件判断
if
基本格式:
# 基本语法# 说明,条件condition 前后有空格[ condition ]# 非空返回 true,可使用 $? 验证,0为 ture,>1 为 false# [ ] 中间只有一个空格的含义就是为空[ condition ] && echo OK || echo notOK //条件满足,执行后面的语句# 常用的判断语句1) = 字符串比较2) 整数比较-lt 小于<-le 小于等于<=-eq 等于 ==-gt 大于 >-ge 大于等于 >=-ne 不等于 !=3) 按照文件的权限 取反!-r 有读-w 有写-x 有执行4) 按照文件类型 取反!-f 文件存在,且普通文件-e 文件存在-d 文件存在,且是目录### 案例:## 1."ok" 是否等于 "ok"if [ "ok" = "ok" ]thenecho "equal"fi## 2.23 是否大于等于22if [ 23 -ge 22 ]thenecho "大于"fi## 3.文件是否存在 /root/school/data.txtif [ -f /root/school/data.txt ]thenecho "存在"fi
多分支:
# 单分支if [ condition ]then代码逻辑fi# 多分支if [ condition ]then代码逻辑elif [ condition ]then代码逻辑fi
case
case $变量名 in"值1")代码逻辑;;"值2")代码逻辑;;*)default 代码逻辑;;esac
for
# 基础语法# 1. 比如 in "$*"/in "$@"for 变量 in 值1 值2 值3 ...do程序done# 2. 有步长for((初始值;循环条件;变量变化))do程序done# 案例 从1加到100,显示最后结果#!/bin/bashSUM=0for((i=1;i<=100;i++))doSUM=$[$SUM+$i]doneecho "SUM=$SUM"
while
while [ condition ]do程序done
read
# 动态读取控制台输入read [option](参数)option:-p:指定提示符-t:等待时间,如果超过就不等了参数:变量:指定读取值的变量名#!/bin/bashread -p "请输入数字" NUM1echo "输入信息为$NUM1"read -t 100 -p "请输入数字" NUM2echo "结果$NUM2"
函数
也是可以分为 系统函数,自定义函数
系统函数
# 举例 basename 用于返回完整路径最后 / 后的内容,不包括 / ,如果有后缀,也把后缀删除了basename [pathname] [suffix(option)]# 举例 dirname 用于返回完整路径最后 / 前的内容,不包括 /dirname /home/aa/ccc/dd.txt
自定义函数
# 函数的定义[ function ] functionName[()]{Action;[return int;]}# 函数的调用functionName [值]# 案例 计算两个参数和,动态获取#!/bin/bash# 声明funciton getSum(){SUM=$[$n1+$n2]echo "sum=$SUM"}read -p "输入加数1:" n1read -p "输入加数2:" n2# 使用getSum $n1 $n2
综合案例
需求分析:
- 脚本放在 /usr/sbin 下,取名 mysql_db_backup.sh
- 每天凌晨2:30备份数据库hspedu到/data/backup/db
- 备份开始和备份结束能够给出相应的提示信息
- 备份后的文件要求以备份时间为文件名,并打包成.tar.gz的形式,比如:2021-03-12_230201.tar.gz
- 在备份的同时,检查是否有10天前备份的数据库文件,如果有就将其删除。
vim /usr/sbin/mysql_db_backup.sh#!/bin/bash# 1.备份目录BACKUP=/data/backup/db# 2.获取当前系统时间DATETIE=$(date +%Y-%m-%d_%H%M%S)# 3.数据库信息## 数据库地址DB_HOST=localhost## 数据库用户名DB_USER=root## 数据库密码DB_PW=root## 需要备份的数据库DATABASE=csz# 4.创建备份目录[ ! -d "${BACKUP}/${DATETIME}" ] $$ mkdir -p "${BACKUP}/${DATETIME}"# 5.备份数据库mysqldump -u${DB_USER} -p${DB_PW} --host=${DB_HOST} -q -R --databases=${DATABASE} | gzip > ${BACKUP}/${DATETIME}/$DATETIME.sql.gz# 6.打成 tar 包,再删除 sql.gz 文件cd ${BACKUP}tar -zcvf $DATETIE.tar.gz ${DATETIE}rm -rf ${BACKUP}/${DATETIE}# 7.删除10前的备份文件,如果有find ${BACKUP} -atime +10 -name "*.tar.gz" -exec rm -rf {} \;echo "数据库配备结束${DATEBASE}"## 创建定时任务crontab -e30 2 * * * /usr/sbin/mysql_db_backup.sh
