- A+
shell脚本
什么是shell?
shell是“壳”的意思,它的主要作用主要是充当解释器为用户和系统内核之间提供一个桥梁。同时shell也是一门脚本语言,利用它可以写一些程序。
shell脚本的执行要求
- 以
#!/bin/bash
开头 - 脚本具有可执行权限
执行方式
- 方式1:chmod命令加权限,然后
./xxx.sh
执行 - 方式2:
sh xxx.sh
执行
注释
# 这是单行注释 :<<! 这是 多行 注释 !
变量
- shell的变量分为系统变量和自定义变量两个,
- 系统变量如:
$HOME
、$PWD
、$SHELL
、$USER
等, - 显示当前shell中的所有变量
set
定义变量
定义变量的格式
语法:变量名=值
#!/bin/bash A=666 echo A=$A # $表示使用变量
定义变量的规则
- 可以有字母、数字、下划线组成,但不能以数字开头
- 等号两侧不能有空格
- 一般习惯用大写
撤销变量
语法:unset 变量名
#!/bin/bash A=123 echo A=$A # 撤销 unset A echo A=$A
静态变量
静态变量是定义后不能被改变的变量(撤销和重新赋值),在变量前面加上readonly即可定义静态变量。
#!/bin/bash readonly A=123 echo A=$A # unset A # 撤销A会报错 # A=222 # 重新赋值也会报错
命令返回值作为变量值
#!/bin/bash # 形式一 A=`date` # 形式二 B=$(date)
设置环境变量
语法:export 变量名=值,假如直接在终端中输入,只是暂时性的设置环境变量,只有当前用户一退出登录,就会失效。要长久保存需要写入到一个文件中:/etc/profile
步骤:
- 在配置文件中写入:export 变量名=值
- 载入:source 配置文件路径
位置参数变量
假如脚本中需要输入参数时如:./myshell.sh 1 2 3
,我们就需要用到位置参数变量。
shell中要拿到命令行的参数,有一套规则:
$n
取一个参数,n为数字,$0
代表命令本身,$1
~$9
代表第一到第九个参数,10个以上的参数时,用大括号括起来,如${10}
。$*
命令行的所有参数,当成一个整体$@
命令行的所有参数,每个参数有区分$#
命令行的参数
比如创建一个myshell.sh
文件,写入如下内容:
#!/bin/bash echo $0 echo $1 echo $2 echo $* echo $@ echo $#
命令行执行:
[lczmx@rH7-1 code]$ sh myshell.sh 11 12 13
返回:
var.sh 11 12 11 12 13 11 12 13 3
预定义变量
预定义变量就是shell设计者事先定义好的变量,我们可以直接在shell中使用。
- $$ 当前进程的进程号
- $! 后台运行的最后一个进程的进程号
- $? 最后一次执行命令的返回状态,0表达上个命令成功,否则表示不正确。
运算符
如何在shell中进性运算操作?shell中有三种方式:
$((运算符))
$[运算符]
`expr m + n`
, 注意要有空格,赋值要有反引号,注意乘法运算符:*
#!/bin/bash # 计算 (4 + 5)*5 # 方式1 RES1=$(((4+5)*5)) echo "res1=$RES1" # 方式2 RES2=$[(4+5)*5] echo "res2=$RES2" # 方式3 TEMP=`expr 4 + 5` RES3=`expr $TEMP * 5` echo "res3=$RES3"
流程控制
条件判断
语法格式一:
if [ 条件 ] then 代码 fi
语法格式二:
if [ 条件 ] then 代码 elif [ 条件 ] then 代码 fi
注意条件前后有空格,可以使用$?
检验
常用判断条件有那些?
- 字符串
=
- 数值
-lt
小于-le
小于等于-eq
等于-gt
大于-ge
大于等于-ne
不等于
- 文件权限
-r
有读权限-w
有写权限-x
有执行权限
- 文件类型
-f
文件-d
目录-e
路径存在
非空返回true, 如:[ hello ]
; 空返回false,如:[ ]
例子
#!/bin/bash ######## 字符串 if [ "abc" = "efs" ] then echo "相等" fi ######## 数值 if [ 12 -eq 12 ] then echo "12 = 12 " fi ######## 文件 if [ -f ./var.sh ] then echo "文件存在" fi
case语句
语法
case $变量名 in 值1) 代码 ;; 值2) 代码 ;; *) # 以上都不符合时执行 代码 ;; esac
例子
#!/bin/bash case $1 in 1) echo "拇指" ;; 2) echo "食指" ;; 3) echo "中指" ;; 4) echo "无名指" ;; 5) echo "小指" ;; *) echo "输入1~5的数" ;; esac
for循环
语法一
for 变量 in 值 do 代码 done
例子
#!/bin/bash # 循环打印参数值 for i in "$*" do echo "num is $i" done echo "==========================" for j in "$@" do echo "num in $j" done
语法二
for (( 初始值; 循环条件; 变量变化 )) do 代码 done
例子
#!/bin/bash # 累加求和 SUM=0 for (( i=0; i<=$1; i++ )) do SUM=$[ $SUM + i ] done echo "结果是$SUM"
while循环
语法
while [ 条件 ] # 注意有空格 do 代码 done
举一个和for循环第二个例子效果一样的例子:
#!/bin/bash # 数字累加求和 SUM=0 i=0 while [ $i -le $1 ] do SUM=$[$SUM+$i] i=$[$i+1] done echo "结果为: $SUM"
read 读取控制台输入
语法
read [选项] 变量
选项
-p 提示内容
-t 等待时间,不写这个时,会一直等待输入
注意:假如是多个变量是需要用空格隔开,而且键盘输入时也用空格分隔
例子:
#!/bin/bash # 读取一个变量 # 等十秒 read -p "输入一个数字" -t 10 NUM1 RES1=$[$NUM1*2] echo "该数字的两倍是:$RES1" # 读取两个变量 read -p "输入两个数字" NUM2 NUM3 RES2=$[$NUM2+$NUM3] echo "这两个数的和为:$RES2"
函数
和其他语言一样,shell也有函数。shell的函数有系统函数和自定义函数之分。
系统函数
系统函数实质上就是我们用到的linux命令,这里讲basename和dirname
basename: 获取文件基本名称
如:basename /home/xxx/a.txt
,回车,显示:a.txt
,
同时可以去除后缀:basename /home/xxx/a.txt .txt
,回车,显示:a
.
而dirname:获取非文件名的目录部分
如:dirname /home/xxx/a.txt
,回车,显示: /home/xxx
自定义函数
语法:
function 函数名 [()] { 代码 [return init;] }
调用时的格式:函数名 [值]
。
例子:
#!/bin/bash function getSum () { RES=$[ $n1+$n2 ] echo "$n1和$n2的和为:$RES" } read -p "输入第一个数:" n1 read -p "输入第二个数:" n2 getSum $n1 $n2
实例 -- 定时备份数据库
- 每天3:30备份数据库到/data/backup/db
- 备份开始和结束时都有提示
- 文件名以备份时间命名,并打包成.tar.gz
- 检查是否有十天前的备份,有则删除
补充,备份命令:
mysqldump -uxxx -pxxx --host=xxx --port=xxx -q -R --databases xxx
参数名 | 缩写 | 含义 |
---|---|---|
--host | -h | 服务器IP地址 |
--port | -P | 服务器端口号 |
--user | -u | MySQL 用户名 |
--pasword | -p | MySQL 密码 |
--databases | -B | 指定要备份的数据库 |
--all-databases | -A | 备份mysql服务器上的所有数据库 |
--quick | -q | 不缓冲查询,直接导出到标准输出。默认为打开状态 |
--routines | -R | 导出存储过程以及自定义函数 |
① 创建一个脚本
vim /home/lczmx/code/backupMysqlData.sh
:
#!/bin/bash BACKUP_PATH=/data/back/db # 备份目录 DATETIME=$(date +%Y-%m-%d_%H%M%S) # 执行date命令,获取当前时间,并格式化 # 数据库地址 DB_HOST=localhost # 数据库端口 DB_PORT=3306 # 数据库用户名 DB_USER=root # 数据库密码 DB_PWD=12345 # 要备份的数据库名 DATEBASE=data # 检查备份目录 [ ! -d "${BACKUP_PATH}/${DATETIME}" ] && mkdir -p "${BACKUP_PATH}/${DATETIME}" # 备份数据库 mysqldump -u${DB_USER} -p${DB_PWD} --host=${DB_HOST} --port=${DB_PORT} -q -R --databases ${DATEBASE} > ${BACKUP_PATH}/${DATETIME}/${DATETIME} # 打包成tar.gz cd ${BACKUP_PATH} # cd过去,使用绝对路径会导致多层目录压缩,即连带/data/...压缩 tar -zcvf ${DATETIME}.tar.gz ${DATETIME} # 删除备份目录 rm -rf ${BACKUP_PATH}/${DATETIME} # 删除超过十天的备份文件, 这是一个固定的用法,find命令后面接-exec可以执行命令 find /data/back/db/ -atime +10 -name "*.tar.gz" -exec rm -rf {} ;
② 设置定时任务
输入:crontab -e
命令,回车后输入以下内容:
30 3 * * * /home/lczmx/code/backupMysqlData.sh