一、什么是Shell
1、为什么要学习Shell
Linux运维工程师在进行服务器集群管理时,需要编写Shell程序来进行服务器管理。
对于JavaEE和Python程序员来说,工作的需要。Boss会要求你编写一些Shell脚本进行程序或者是服务器的维护,比如编写一个定时备份数据库的脚本。对于大数据程序员来说,需要编写Shell程序来管理集群。
2、Shell是什么
Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序
用户可以用Shell来启动、挂起、停止甚至是编写一些程序。


3、Shell脚本的执行方式
1.格式要求
以 #!/bin/bash 开头
需要可执行权限
2.常用执行方式
(1)使用脚本的绝对路径或相对路径
首先要赋予想运行的helloword.sh 脚本的+x权限,再执行脚本
(2)sh 脚本
不用赋予脚本+x权限,直接执行即可
二、Shell的变量
1、变量介绍
Linux Shell中的变量分为:系统变量和用户自定义变量。
系统变量:HOME、PWD、SHELL、USER等等,比如:echo $HOME
显示当前shell中所有变量:set
2、Shell变量的定义
1.基本语法
定义变量 : 变量=值
撤销变量:unset 变量
声明静态变量:readonly 变量。不可unset
2.示例
创建脚本 var.sh

1)定义变量A
2)撤销变量A
3)声明静态的变量B=2,不能unset


4)可把变量提升为全局环境变量,可供其他Shell程序使用
3.Shell变量的定义规则
变量名称可以由字母、数字和下划线组成,但是不能以数字开头。5A=200(x)
等号两侧不能有空格
变量名称一般习惯为大写 ,这是规范
4.将命令的返回值赋给变量
A=`date`,反引号,运行里面的命令,并把结果返回给变量A
A=$(date),等价于反引号

3、设置环境变量
1.基本语法
export 变量名=变量值:将shell变量输出为环境变量/全局变量
source 配置文件:让修改后的配置信息立即生效
echo $变量名:查询环境变量的值
2.示例
1)在/etc/profile文件中定义TOMCAT HOME环境变量

2)查看环境变量TOMCAT HOME的值

3)在另外一个shell程序中使用 TOMCAT HOME

4、设置位置参数变量
1.介绍
当我们执行一个shell脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量
比如 :./myshell.sh 100 200,这个就是一个执行shell的命令行,可以在myshell 脚本中获取到参数信息
2.基本语法
n:n为数字,0代表命令本身,1-9代表第一到第九个参数,十以上的参数需要用大括号包含,如${10}
\*:这个变量代表命令行中所有的参数,*把所有的参数看成一个整体
@:这个变量也代表命令行中所有的参数,不过@把每个参数区分对待
$#:这个变量代表命令行中所有参数的个数
3.示例
编写一个Shell脚本 position.sh ,在脚本中获取到命令行的各个参数信息

5、设置预定义变量
1.基本介绍
Shell设计者预先定义好的变量,可以直接在Shell脚本中使用
2.基本语法
:当前进程的进程号(PID) $!:后台运行的最后一个进程的进程号(PID) $?:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。 #### 3.示例 在Shell脚本 preVar.sh 中简单使用一个预定义变量  ## 三、运算符 ### 1、基本语法 $((运算式)) 或 $\[运算式\] 或者 expr m + n expr m - n expr \\\*,/ ,% :乘,除,取余 注:expr运算符间要有空格。如果希望将expr的结果赋给某个变量,使用反引号(\`\`) ### 2、示例 计算(2+3)\*4的值  请求出命令行的两个参数\[整数\]的和 20 50  ## 四、条件判断 ### 1、基本语法 \[ condition \] 注:condition 和中括号之间有空格 非空返回true,可使用$? 验证(0为true,\>1 为false) 示例: \[ goose \] :返回true \[ \] :返回false \[ condition \] \&\& echo OK \|\| echo 不OK:条件满足,执行后面的语句 ### 2、常用判断 1.=字符串比较 2.两个整数的比较 * -lt 小于 * -le 小于等于 little equal * -eq 等于 * -gt 大于 * -ge 大于等于 * -ne 不等于 3.按照文件权限进行判断 * -r 有读的权限 * -w 有写的权限 * -x 有执行的权限 4.按照文件类型进行判断 * -f 文件存在并且是一个常规的文件 * -e 文件存在 * -d 文件存在并是一个目录 ### 3、示例 1."ok" 是否等于 "ok" #!/bin/bash if [ "ok" = "ok" ] then echo "equal" fi  2.23是否大于等于22 #!/bin/bash if [ "ok" = "ok" ] then echo "equal" fi if [ 23 -ge 22 ] then echo "Yes" fi  3./root/aaa.txt 是否存在 #!/bin/bash if [ "ok" = "ok" ] then echo "equal" fi if [ 23 -ge 22 ] then echo "Yes" fi if [ -f /root/aaa.txt ] then echo "存在" fi  ## 五、流程控制 ### 1、 if语句 #### 1.单分支 #!/bin/bash if [ condition ] then echo "输出" fi #### 2.多分支 #!/bin/bash if [ condition ] then 操作 elif [ condition ] then 操作 fi #### 3.示例 输入的参数大于等于60,则输出"及格了",否则输出"明年再见" #!/bin/bash if [ $1 -ge 60 ] then echo "及格了" elif [ $1 -le 60 ] then echo "明年见" fi  ### 2、case语句 #### 1.基本语法 case $变量名 in "值1") 操作 ;; "值2") 操作 ;; *) 操作 #上述值都不满足,执行这块操作 ;; esac #### 2.示例 命令参数是1时输出"周一",2输出"周二",其他输出"other" #!/bin/bash case $1 in "1") echo "周一" ;; "2") echo "周二" ;; *) echo "other" ;; esac  ### 3、for语句 #### 1.基本语法 语法1 for 变量 in 值1 值2 值3... do 操作 done 语法2 #### 2.示例 示例1:打印命令行输入的参数 #!/bin/bash for i in "$*" do echo "num is $i" done for j in "$@" do echo "num is $j" done  示例2:从1加到100的值输出显示 #!/bin/bash SUM=0 for(( i=1; i<=100; i++)) do SUM=$[$SUM+$i] done echo SUM=$SUM  ### 4、while 循环 #### 1.基本语法 while [ 条件判断式 ] do 操作 done 注意:while 和 条件判断式的 \[ 之间有空格 #### 2.示例 从命令行输入一个数n,统计从1 累加到 n 的值是多少 #!/bin/bash i=1 SUM=0 while [ $i -le $1 ] do SUM=$[$SUM+$i] i=$[$i+1] done echo SUM=$SUM  ### 5、read读取控制台输入 #### 1.基本语法 read \[选项\] \[参数\] #### 2.常用选项 -p :指定读取值时的提示符 -t :指定读取值时的等待时间(秒),如果没有在指定的时间内输入,就不再等待 #### 3.参数 变量:指定读取值的变量名 #### 4.示例 (1)读取控制台输入的一个NUM1值  (2)读取控制台输入的一个NUM2值,在10秒内输入  超过10秒后自动退出 ## 六、函数 ### 1、函数介绍 Shell编程和其它编程语言一样,有系统函数,也可以自定义函数。系统函数中,我们这里就介绍两个。 #### 1.系统函数 (1)basename 功能: 返回完整路径最后 / 的部分,常用于获取文件名 基本语法:basename \[pathname\] \[suffix\] basename \[string\] \[suffix\] basename命令会删掉所有的前缀,包括最后一个 " / " 字符,然后将字符串显示出来 选项 \[suffix\]:如果suffix被指定了,basename会将pathname或string中的suffix去掉 示例:返回/home/aaa/test.txt 的 " test.txt " 部分  (2)dirname 功能:返回完整路径最后 / 的前面的部分,常用于返回路径部分 基本语法:dirname 文件绝对路径 从给定的包含绝对路径文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录部分) 示例:返回 /home/aaa/test.txt 的 /home/aaa 部分  #### 2.自定义函数 (1)基本语法 [function] funname[()] { Action; [return int;] } 调用直接写函数名 : funname \[值\] 示例: 自定义函数getSum,计算输入两个参数的和  ## 七、综合案例------定时备份数据库 ### 1、要求 每天凌晨 2:30 备份 数据库 goose 到 /data/backup/db 备份开始和备份结束能够给出相应的提示信息 备份后的文件要求以备份时间为文件名,并打包成.tar.gz 的形式,比如:2021-0312 230201.tar.gz 在备份的同时,检查是否有10天前备份的数据库文件,如果有就将其删除。 #!/bin/bash # 备份目录 BACKUP=/data/backup/db # 当前时间 DATETIME=$(date +%Y-%m-%d_%H%M%S) echo $DATETIME # 数据库的地址 HOST=localhost DB_USR=root DB_PASSWD=goose000 DATABASE=goose # 创建备份目录 # 如果不存在就创建,如果存在就直接使用 [ ! -d "${BACKUP}/${DATETIME}" ] && mkdir -p "${BACKUP}/${DATETIME}" # 备份数据库 mysqldump -u${DB_USR} -p${DB_PASSWD} --host=${HOST} -q -R --databases ${DATABASE} | gzip > ${BACKUP}/${DATETIME}/$DATETIME.sql.gz # 将文件处理成tar.gz cd ${BACKUP} tar -zcvf $DATETIME.tar.gz ${DATETIME} # 删除对应的备份目录 rm -rf ${BACKUP}/${DATETIME} # 删除10天前的备份文件 find ${BACKUP} -atime +10 -name "*.tar.gz" -exec rm -rf {} \; echo "备份数据库 ${DATABASE} 成功" 接着使用crontab -e命令,输入 30 2 * * * /usr/sbin/mysql_db_backup.sh