shell编程
- vim hello.sh
#!/bin/bash(zsh) echo "helloworld!"
-
脚本的常用执行方式
- 方式一:输入脚本的绝对路径或相对路径,需要先赋予hello.sh脚本的x权限,sudo chmod u+x hello.sh
- 方式二:(sh + 脚本)说明:不用赋予脚本+x权限,直接执行 比如 sh hello.sh
-
Shell的变量
变量分为:系统变量和用户自定义变量
- 系统变量: H O M E 、 HOME、 HOME、PWD、 S H E L L 、 SHELL、 SHELL、USER等等,比如echo $HOME等等
- 显示当前shell中所有变量:set
shell变量的定义
- 定义变量:变量名=值
- 撤销变量:unset 变量
- 声明静态变量:readonly变量,注意:不能unset
案例
-
定义变量A
vim var.sh
#!/bin/bash(zsh) A=100 echo $A # ./var.sh --100 echo A=$A # ./var.sh --A=100 echo "A=$A" # ./var.sh --A=100
-
撤销变量
unset A
-
声明静态变量
readonly B=2 echo "B=$B" #unset B --不可以unset B #显示行号 :nu
shell变量命名规则
- 变量名称可以由字母、数字、下划线组成,但是不能以数字开头
- 等号两侧不能有空格
- 变量名称一般习惯大写
将命令的返回值赋给变量
A=`date` #反引号,运行里面的命令,并把结果返回给变量A A=$(date) #等价于反引号
-
设置环境变量
export 变量名=变量值 #功能描述:将shell变量输出为环境变量/全局变量 source 配置文件 #功能描述:让修改后的配置信息立即生效 echo $变量名 #功能描述:查询环境变量的值
-
快速入门
#1.在/etc/profile文件中定义TOMCAT_HOME环境变量 tomcat位于/opt/ 文件目录下 vim /etc/profile export TOMCAT_HOME=/opt/tomcat sourse /etc/profile #2.查看环境变量的值 echo $TOMCAT_HOME #3.在另外一个shell程序中使用TOMCAT_HOME vim var.sh echo "tomcat_home=$TOMCAT_HOME" :<<! 多行注释 !
-
-
位置参数变量
当我们执行一个shell脚本时,如果希望获取到命令行的参数信息,就可以使用到未知参数变量
-
基本语法
- $n (功能描述:n为数字,$0代表目录本身,$1- 9 代 表 第 一 到 第 九 个 参 数 , 十 以 上 的 参 数 需 要 用 大 括 号 包 含 , 如 9代表第一到第九个参数,十以上的参数需要用大括号包含,如 9代表第一到第九个参数,十以上的参数需要用大括号包含,如{10})
- ∗ ( 功 能 描 述 : 这 个 变 量 代 表 命 令 行 中 所 有 的 参 数 , * (功能描述:这个变量代表命令行中所有的参数, ∗(功能描述:这个变量代表命令行中所有的参数,*把所有的参数看成一个整体)
- @ ( 功 能 描 述 : 这 个 变 量 也 代 表 命 令 行 中 所 有 的 参 数 , 不 过 @ (功能描述:这个变量也代表命令行中所有的参数,不过 @(功能描述:这个变量也代表命令行中所有的参数,不过@把每个参数区分对待)
- $# (功能描述:这个变量代表命令行中所有参数的个数)
-
案例:
编写一个shell脚本,position.sh,在脚本中获取到命令行的各个参数信息
-
-
预定义变量
就是shell设计者事先已经定义好的变量,可以直接在shell脚本中使用
- 基本语法
- $$ (功能描述:当前进程的进程号(PID))
- $! (功能描述:后台运行的最后一个进程的进程号(PID))
- $?(功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值非0,则证明上一个命令执行不正确了)
- 基本语法
-
运算符
-
基本语法
- " $((运算式))“或”$[运算式]"或者expr m + n
- 注意expr运算符间要有空格,如果希望将expr的结果赋给某个变量,使用``
- expr m - n
- expr \*,/,% 乘,除,取模
-
实例
-
计算(2+3)*4的值
vim operator.sh #!bin/bash #第一种方式: RES1=$(((2+3)*4)) echo "res1=$RES1" #第二种方式 RES2=$[(2+3)*4] echo "res2=$RES2" #推荐使用 #第三种方式 TEMP=`expr 2 + 3` #注意要用空格,否则输出结果为 2+3 RES3=`expr $TEMP \* 4` echo "temp=$TEMP" echo "res3=$RES3"
-
求出命令行的两个参数[整数]的和 20 50
SUM=$[$1+$2] echo "sum=$SUM"
然后再命令行输入 ./operator.sh 20 50 --输出结果 sum=70
-
-
-
条件判断
-
基本语法
[ condition ] (注意condition前后要有空格) 非空返回true,可使用$?验证(0为true,>1为false)
-
示例
[ abc ] --返回true [] --返回false [ condition ] && echo ok || echo notok 条件满足执行后边的语句
-
判断语句
-
常用判断条件
1)= 字符串比较,判断两个字符串是否相等 2)两个整数的比较 -lt 小于 -le 小于等于 -eq 等于 -gt 大于 -ge 大于等于 -ne 不等于 3)按照文件权限划分 -r 有读的权限 -w 有写的权限 -x 有执行的权限 4)按照文件类型划分 -f 文件存在并且是一个常规文件 -e 文件存在 -d 文件存在并是一个目录
-
应用实例
vim ifdemo.sh #!bin/bash #案例1:判断"ok"是否等于"ok" if [ "ok" = "ok" ] then echo "equal" fi #案例2:23是否大于等于22 if [ 23 -ge 22 ] then echo "大于" fi #案例3:/root/shcode/aaa.txt 判断目录中的文件是否存在 if [ -f /root/shcode/aaa.txt ] then echo "存在" fi
-
-
-
流程控制
多分支语句
案例:如果输入的参数大于60,则输出及格了,否则输出不及格
#!/bin/bash if [ $1 -ge 60 ] then echo "及格了" elif [ $1 -lt 60 ] then echo "不及格"
case语句
#!/bin/bash
case $1 in
"1")
echo "周一"
;;
"2")
echo "周二"
;;
"3")
echo "周三"
;;
*)
echo "Other.."
;;
esac
-
for语句
vim testFor1.sh #!/bin/bash #基本语法1 << comment for 变量 in 值1 值2 值3... do 程序主代码 done comment #案例1:打印命令行输入的参数 for i in "$*" # $*把所有的参数看成一个整体 do echo "num is $i" #这里只会输出一句话 done for j in "$@" #$@把每个参数区分对待 do echo "num is $j" done #基本语法2 for ((初始值;循环控制条件;变量变化)) do 主程序代码 done #案例2:从1到100的值累加显示 SUM=0 for ((i=1; i<=100; i++)) do SUM=$[$SUM+$I] done echo "sum=$SUM"
while语句
while [ 条件判断式 ]
do
程序
done
vim testWhile.sh #!/bin/bash #案例1:从命令行输入一个参数n,统计1+2+..+n SUM=0 i=0 while [ $i -le $1 ] do SUM=$[$SUM+$i] # i自增 i=$[$i+1] done echo "结果=$SUM"
-
read获取控制台输入
read(选项)(参数) 选项: -p:指定读取值时的提示符 -t:指定读取值时等待的时间(秒),如果没有在指定时间内输入,就不再等待了 参数:变量:指定读取值的变量名 #实例:testRead.sh #案例1:读取控制台输入一个num值 #!/bin/bash read -P "请输入一个数num=" NUM1 echo "你输入的num=$NUM1" #案例2:读取控制台输入一个num值,在10秒内输入 read -t 10 -P "请输入一个数num=" NUM2 echo "你输入的num=$NUM2"
-
函数
-
系统函数
basename:功能为返回完整路径的最后/的部分,常用于获取文件名
basename [pathname] [suffix] (选项suffix为后缀,如果suffix被指定了,basename会将pathname或string的suffix去掉) basename [string] [suffix] (功能:basename命令后会删掉所有的前缀包括最后一个/字符,然后将字符串显示出来) #案例1:返回/home/aaa/test.txt的"test.txt"部分 basename /home/aaa/test.txt --test.txt basename /home/aaa/test.txt .tst --test
dirname:功能为返回完整路径最后/的前面部分,常用于返回路径部分
dirname /home/aaa/test.txt --/home/aaa
-
自定义函数
function funname () { Action; [return int;] } #调用时直接写函数名:funname [参数值] #案例1:计算输入的两个参数的和(动态获取) vim testFunc.sh #!/bin/bash #定义函数 function getSum(){ SUM=$[$n1+$n2] echo "和=$SUM" } #控制台输入两个值 read -P "请输入一个数n1=" n1 read -P "请输入一个数n2=" n2 #调用 getSum $n1 $n2
-
-
Shell编程综合案例
-
需求分析:
1.每天凌晨2:30备份数据库hspedu到 /data/backup/db
2.备份开始和结束能够给出相应的提示信息
3.备份后的文件要求以备份时间为文件名,并打包成.tar.gz的形式,比如2021-04-10_104515.tar.gz
4.在备份的同时,检查是否有10天前备份的数据库文件,如果有就将其删除
#!/bin/bash #备份目录 BACKUP=/data/backup/db #获取当前时间 DATETIME=$(date +%Y-%m-%d_%H%M%S) #数据库的地址 HOST=localhost #数据库用户名 DB_USER=root #数据库密码 DB_PW=root #备份的数据库 DATABASE=hspedu #创建备份目录,如果不存在就创建,如果存在就直接使用 [ ! -d "${BACKUP}/${DATETIME}" ] && mkdir -p "${BACKUP}/${DATETIME}" #! -d 表示如果不是一个目录 {}为可选的 #备份数据库 -q -R表示若有多个数据库都备份 mysqldump -u${DB_USER} -p${DB_PW} --host=${HOST} -q -R --datebases ${DATABASE} | gzip > ${BACKUP}/${DATETIME}/$DATETIME.sql.gz #将文件处理成tar.gz形式 cd ${BACKUP} tar -zcvf $DATETIME.tar.gz ${DATETIME} # 将${DATETIME}压缩为$DATETIME.tar.gz #删除备份的文件夹目录及之下的文件 rm -rf ${BACKUP}/${DATETIME} #检查是否有十天前备份的文件,将其删除 find ${BACKUP} -atime +10 -name "*.tar.gz" -exec rm -rf {} \; #-atime +10 查找十天前创建的备份文件 echo "备份数据库${DATABASE}成功" #设置定时任务 crontab -e 30 2 * * * /usr/sbin/mysql_db_backup.sh(以上所写脚本文件所在目录)
-