网页网站制作公司,企业手机端网站模板,遵义网站开发制作公司,网站上的图片怎么做17 Linux之大数据定制篇-Shell编程 文章目录 17 Linux之大数据定制篇-Shell编程17.1 Shell编程简介17.1.1 为什么要学习Shell编程17.1.2 Shell是什么17.1.3 执行Shell脚本 17.2 Shell的变量17.2.1 Shell变量介绍17.2.2 设置环境变量17.2.3 位置参数变量17.2.4 预定义变量 17.3 …17 Linux之大数据定制篇-Shell编程 文章目录 17 Linux之大数据定制篇-Shell编程17.1 Shell编程简介17.1.1 为什么要学习Shell编程17.1.2 Shell是什么17.1.3 执行Shell脚本 17.2 Shell的变量17.2.1 Shell变量介绍17.2.2 设置环境变量17.2.3 位置参数变量17.2.4 预定义变量 17.3 Shell基本操作17.3.1 运算符17.3.2 条件判断及三元运算符17.3.3 read读取控制台输入 17.4 Shell流程控制17.4.1 if判断17.4.2 case语句17.4.3 for循环17.4.4 while循环 17.5 函数17.5.1 系统函数17.5.2 自定义函数 17.6 Shell编程综合案例 学习视频来自于B站【小白入门 通俗易懂】2021韩顺平 一周学会Linux。可能会用到的资料有如下所示下载链接见文末 《鸟哥的Linux私房菜 基础学习篇 第四版》1《鸟哥的Linux私房菜 服务器架设篇 第三版》2《韩顺平_2021图解Linux全面升级》3 17.1 Shell编程简介
17.1.1 为什么要学习Shell编程 Shell才是Linux的精华Shell几乎是IT企业必须使用的运维自动化编程语言特别是在运维工作中的服务监控、业务快速部署、服务启动停止、数据备份及处理、日志分析等环节里shell是不可缺的。工作角度来讲学习 Shell 是为了提高我们自己工作效率提高产出让我们在更少的时间完成更多的事情。比如下面给出几个需要Shell开发的场景中 Linux运维工程师在进行服务器集群管理时需要编写Shell程序来进行服务器管理。对于JavaEE和Python程序员来说工作的需要你的老大会要求你编写一些Shell脚本进行程序或者是服务器的维护比如编写一个定时备份数据库的脚本。对于大数据程序员来说需要编写Shell程序来管理集群。 更多可以查看知乎文章“Shell 编程入门”。 对于初学者来说不必学的太复杂只要熟练掌握基本语法并且能看懂别人的Shell脚本即可。
17.1.2 Shell是什么 Shell是一个命令行解释器它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序用户可以用Shell来启动、挂起、停止甚至是编写一些程序。如下图所示 #mermaid-svg-UnTllGX2w5cnqISt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-UnTllGX2w5cnqISt .error-icon{fill:#552222;}#mermaid-svg-UnTllGX2w5cnqISt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UnTllGX2w5cnqISt .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-UnTllGX2w5cnqISt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UnTllGX2w5cnqISt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UnTllGX2w5cnqISt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UnTllGX2w5cnqISt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UnTllGX2w5cnqISt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UnTllGX2w5cnqISt .marker.cross{stroke:#333333;}#mermaid-svg-UnTllGX2w5cnqISt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UnTllGX2w5cnqISt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-UnTllGX2w5cnqISt .cluster-label text{fill:#333;}#mermaid-svg-UnTllGX2w5cnqISt .cluster-label span{color:#333;}#mermaid-svg-UnTllGX2w5cnqISt .label text,#mermaid-svg-UnTllGX2w5cnqISt span{fill:#333;color:#333;}#mermaid-svg-UnTllGX2w5cnqISt .node rect,#mermaid-svg-UnTllGX2w5cnqISt .node circle,#mermaid-svg-UnTllGX2w5cnqISt .node ellipse,#mermaid-svg-UnTllGX2w5cnqISt .node polygon,#mermaid-svg-UnTllGX2w5cnqISt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UnTllGX2w5cnqISt .node .label{text-align:center;}#mermaid-svg-UnTllGX2w5cnqISt .node.clickable{cursor:pointer;}#mermaid-svg-UnTllGX2w5cnqISt .arrowheadPath{fill:#333333;}#mermaid-svg-UnTllGX2w5cnqISt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UnTllGX2w5cnqISt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UnTllGX2w5cnqISt .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-UnTllGX2w5cnqISt .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-UnTllGX2w5cnqISt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UnTllGX2w5cnqISt .cluster text{fill:#333;}#mermaid-svg-UnTllGX2w5cnqISt .cluster span{color:#333;}#mermaid-svg-UnTllGX2w5cnqISt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-UnTllGX2w5cnqISt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 无法直接执行 Shell指令如mkdir /opt/tomShell脚本如hello.sh Shell命令解释器 Linux内核 图17-1 Shell示意图 Linux系统中不止一个Shell常见的有bash(ba shell)、tcsh(tc shell)、csh(c shell)等在国内常用的是bash。
17.1.3 执行Shell脚本
首先来说一下Shell脚本格式要求 脚本以#!/bin/bash开头因为国内常用bash。注意这里的#!是一个特殊的表示符后面紧跟着的/bin/bash是解释此脚本的shell路径。脚本的名称后缀约定俗成为.sh但即使不是该后缀也可以运行。 那有了Shell脚本之后便有如下两种执行Shell脚本的方式【重点】 【方式1】使用sh指令格式为sh脚本不用赋予脚本执行权限(x权限)直接执行即可。【方式2】直接输入脚本路径注意首先要赋予Shell脚本执行权限(x权限)再输入路径执行脚本。 下面展示一个应用案例 【案例1】创建一个Shell脚本输出“hello,shell!”。
# 1. 编写Shell脚本hello.sh
[rootCentOS76 ~]# mkdir /root/myshcode # 创建一个文件夹专门用于存放shell脚本
[rootCentOS76 ~]# cd /root/myshcode/
[rootCentOS76 myshcode]# vim hello.sh
######################################
# 输入以下代码注意第一行不是注释
#!/bin/bash
echo hello,shell!
####################################### 2. 执行方式1
[rootCentOS76 myshcode]# sh hello.sh
hello,shell!# 3. 执行方式2
[rootCentOS76 myshcode]# ./hello.sh
-bash: ./hello.sh: 权限不够
[rootCentOS76 myshcode]# chmod ux hello.sh
[rootCentOS76 myshcode]# ll
总用量 4
-rwxr--r--. 1 root root 32 7月 29 10:41 hello.sh
[rootCentOS76 myshcode]# ./hello.sh
hello,shell!17.2 Shell的变量
17.2.1 Shell变量介绍 Linux Shell中的变量分为 环境变量 和 用户自定义变量。 环境变量 就是Linux系统中自带的变量这是一种全局变量不管在哪个目录下的Shell脚本中都可以直接使用比如$HOME、$PWD、$SHELL、$USER等。
# 常见的系统变量
$PATH 指定命令的搜索路径
$HOME 指定用户的主工作目录(即用户登陆到Linux系统中时默认的目录
$SHELL 当前Shell它的值通常是/bin/bash。
$PWD 当前的工作目录
$USER 当前登录用户# 显示系统变量
echo $HOME 显示家目录
set 显示当前shell中所有变量用户自定义变量就是用户自己定义的变量作用范围一般也就局限在当前的Shell脚本中。实际工作中最常用的是自定义变量。下面给出用户自定义变量的一些常用语法
# 基本语法-shell脚本自定义变量的操作
变量名值 # 1. 定义变量注意没有空格
unset 变量名 # 2. 撤销变量
readonly 变量名 # 3. 声明静态变量但注意不能unset撤销
echo $变量名 # 4. 输出变量时要加上$
# 注释内容 # 5. 单行注释
# 6. 多行注释
:!
多行内容
!# 基本语法-将命令的返回值赋给变量
A指令 # 运行里面的命令并把结果返回给变量A。
# Adate就是将当前时间(比如“2023年 08月 22日 星期二 12:03:44 CST”)赋给了A。
# Adate就是将单词date赋值给变量A。
A$(指令) # 等价于 A指令当然Shell编程中对于自定义变量的名称也有一些约定俗成的规定 变量名称可以由字母、数字和下划线组成但是不能以数字开头。5A200(不允许)变量名称一般习惯为大写但是小写也可以运行。定义变量时等号两侧不能有空格(强制规定)。 下面创建/home/myshcode/var.sh并展示四个应用案例
# 创建源代码文件
[rootCentOS76 myshcode]# vim var.sh
########################################
# 下面是var.sh中的源代码注意下面第一行不是注释
#!/bin/bash
# 案例1定义变量A
A30
echo A$A
echo A$A# 案例2撤销变量A
unset A
echo A$A# 案例3声明静态的变量B2不能unset
readonly B2
echo B$B
unset B# 案例4将指令返回的结果赋值给变量
Cdate
D$(date)
echo C$C
echo D$D
########################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh var.sh
A30
A30
A
B2
var.sh: 第 14 行:unset: B: 无法反设定: 只读 variable
C2023年 07月 29日 星期六 11:18:07 CST
D2023年 07月 29日 星期六 11:18:07 CST17.2.2 设置环境变量 #mermaid-svg-sT7z8SpY68gPjpXu {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-sT7z8SpY68gPjpXu .error-icon{fill:#552222;}#mermaid-svg-sT7z8SpY68gPjpXu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sT7z8SpY68gPjpXu .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-sT7z8SpY68gPjpXu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sT7z8SpY68gPjpXu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sT7z8SpY68gPjpXu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sT7z8SpY68gPjpXu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sT7z8SpY68gPjpXu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sT7z8SpY68gPjpXu .marker.cross{stroke:#333333;}#mermaid-svg-sT7z8SpY68gPjpXu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sT7z8SpY68gPjpXu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-sT7z8SpY68gPjpXu .cluster-label text{fill:#333;}#mermaid-svg-sT7z8SpY68gPjpXu .cluster-label span{color:#333;}#mermaid-svg-sT7z8SpY68gPjpXu .label text,#mermaid-svg-sT7z8SpY68gPjpXu span{fill:#333;color:#333;}#mermaid-svg-sT7z8SpY68gPjpXu .node rect,#mermaid-svg-sT7z8SpY68gPjpXu .node circle,#mermaid-svg-sT7z8SpY68gPjpXu .node ellipse,#mermaid-svg-sT7z8SpY68gPjpXu .node polygon,#mermaid-svg-sT7z8SpY68gPjpXu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sT7z8SpY68gPjpXu .node .label{text-align:center;}#mermaid-svg-sT7z8SpY68gPjpXu .node.clickable{cursor:pointer;}#mermaid-svg-sT7z8SpY68gPjpXu .arrowheadPath{fill:#333333;}#mermaid-svg-sT7z8SpY68gPjpXu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sT7z8SpY68gPjpXu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sT7z8SpY68gPjpXu .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-sT7z8SpY68gPjpXu .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-sT7z8SpY68gPjpXu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sT7z8SpY68gPjpXu .cluster text{fill:#333;}#mermaid-svg-sT7z8SpY68gPjpXu .cluster span{color:#333;}#mermaid-svg-sT7z8SpY68gPjpXu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sT7z8SpY68gPjpXu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} /etc/profile文件定义export A变量值 a.sh可调用A b.sh可调用A 图17-2 环境变量示意图 既然前面提到了环境变量那么本节就来介绍一下如何添加一个新的环境变量。全局环境变量信息一般都存储在/etc/profile中于是在Linux任意目录下的一个Shell脚本都可以调用这个文件中的环境变量(如上图所示)。设置环境变量的语法如下
# 基本语法-设置环境变量
## 在/etc/profile文件中设置
export 变量名变量值 # 将shell变量输出为环境变量/全局变量
## 在终端窗口设置
source 配置文件 # 让修改后的配置信息立即生效
echo $变量名 # 查询环境变量的值下面展示一个应用案例 【案例1】在/etc/profile文件中定义TOMCAT_HOME的安装路径/opt/tomcat为环境变量然后分别在终端、脚本/home/myshcode/a.sh查看环境变量TOMCAT_HOME的值。
# 1. 添加环境变量
[rootCentOS76 myshcode]# vim /etc/profile
##########################################
# 在文件末尾添加下面一行
export TOMCAT_HOME/opt/tomcat
########################################### 2. 在设置生效前后查看环境变量的值
[rootCentOS76 myshcode]# echo $TOMCAT_HOME[rootCentOS76 myshcode]# source /etc/profile
[rootCentOS76 myshcode]# echo $TOMCAT_HOME
/opt/tomcat# 3. 编写/home/myshcode/a.sh查看环境变量
[rootCentOS76 myshcode]# vim a.sh
####################################
# 编写如下两行代码
#!/bin/bash
echo TOMCATHOME$TOMCAT_HOME
####################################
[rootCentOS76 myshcode]# sh a.sh
TOMCATHOME/opt/tomcat17.2.3 位置参数变量 那在平常编程过程中常常会遇到“形式参数”这个概念。类似的显然有时候Shell脚本中的参数需要由外部定义那此时“所传递的变量”就是“位置参数变量”。不过无需重新起变量名之类的操作顾名思义“位置参数变量”显然和顺序有关系。下面这几个特定的符号代表了不同的“位置参数变量”需求
# 基本语法-调用位置参数变量
$n # n为数字$0代表命令本身$1-$9代表第一到第九个参数十以上的参数需要用大括号包含如${1O}。
$* # 这个变量代表命令行中所有的参数$*把所有的参数看成一个整体
$ # 这个变量代表命令行中所有的参数不过$把每个参数区分对待
$# # 这个变量代表命令行中所有参数的个数比如在终端执行Shell脚本 ./myshell.sh 100 200那么在myshell脚本中$1表示100、$2表示200、$#为2表示有两个参数$常用于遍历所有元素$*常用于直接输出所有的输入参数两者的区别可以见下面的“for循环语法”一节。
下面展示一个应用案例 【案例1】编写一个shell脚本/home/myshcode/box.sh在脚本中获取到命令行的长、宽、高三个参数信息并输出。
# 编写代码文件
[rootCentOS76 myshcode]# vim box.sh
####################################
# 输入以下代码
#!/bin/bash
echo 长$1,宽$2高$3
echo 长宽高$*
echo 长宽高$
echo 输入的参数个数$#
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh box.sh 3 4 5
长3,宽4高5
长宽高3 4 5
长宽高3 4 5
输入的参数个数317.2.4 预定义变量 “预定义变量”就是shell设计者事先已经定义好的变量可以直接在shelI脚本中使用。这个用的并不是很多所以只是简单介绍一下。
# 常见的预定义变量
$$ # 当前进程的进程号(PID)
$! # 后台运行的最后一个进程的进程号(PID)
$? # 最后一次执行的命令的返回状态。0(正确执行)/非0(不正确执行)下面展示一个应用实例 【案例1】在一个shell脚本/home/myshcode/preVar.sh中简单使用一下预定义变量。
# 编写代码文件
[rootCentOS76 myshcode]# vim preVar.sh
####################################
# 输入以下代码
#!/bin/bash
echo 当前执行的进程ID$$
# 以后台方式运行一个脚本并获取它的进程号
/root/myshcode/a.sh #表示取地址
echo 最后一个后台方式运行的进程ID$!
echo 执行的结果是$?
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh preVar.sh
当前执行的进程ID28344
最后一个后台方式运行的进程ID28345
执行的结果是0
[rootCentOS76 myshcode]# TOMCATHOME/opt/tomcat
^C
[rootCentOS76 myshcode]#
# 注因为在脚本里面运行了另一个脚本所以卡住了ctrlc退出。17.3 Shell基本操作
17.3.1 运算符
本小节学习如何在shell中进行各种运算操作也就是加减乘除
# 基本语法-运算符
$((运算式)) # 方式1太麻烦不推荐
$[运算式] # 方式2推荐
expr m n # 方式3注意expr运算符间要有空格;如果希望将expr的结果赋给某个变量使用# 运算符方式3-expr加
- 减
\* 乘
/ 除
% 取余下面展示两个应用实例 【案例1】计算(23)x4的值。 【案例2】计算命令行的两个整数参数的和。
# 编写代码文件
[rootCentOS76 myshcode]# vim oper.sh
####################################
# 输入以下代码
#!/bin/bash
# 案例1计算(23)x4的值
# 方式1$(())
RES1$(((23)*4))
echo res1$RES1
# 方式2$[]
RES2$[(23)*4]
echo res2$RES2
# 方式3使用expr
TEMPexpr 2 3
RES3expr $TEMP \* 4
echo temp$TEMP, res3$RES3# 案例2请求出命令行的两个参数[整数]的和
SUM$[$1$2]
echo sum$SUM
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh oper.sh 30 50
res120
res220
temp5, res320
sum8017.3.2 条件判断及三元运算符
本小节来介绍Shell编程中条件判断语法以及三元运算符(一种简便的if-else形式)。
# 基本语法-判断语句
[ condition ] # 注意condition前后要有空格。
# condition非空返回true可使用$?验证(0为true,1为false)。# 应用实例-判断语句
[ hello ] # 返回true
[ ] # 返回false注意空格
[ condition ] 语句1 || 语句2 # 三元运算符条件为真执行语句1否则执行语句2# 常用判断条件
# 1.字符串比较字符串比较
# 2.两个整数的比较
-lt 小于little
-le 小于等于littleequal
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于
# 3.按照文件权限进行判断
-r 有读的权限
-w 有写的权限
-x 有执行的权限
# 4.按照文件类型进行判断
-f 文件存在并且是一个常规的文件
-e 文件存在
-d 文件存在并是一个目录下面站是三个应用实例 【案例1】“ok是否等于ok”。 【案例2】23是否大于等于22。 【案例3】/root/shcode/aaa.txt目录中的文件是否存在。
# 编写代码文件
[rootCentOS76 myshcode]# vim ifdemo.sh
####################################
# 输入以下代码
#!/bin/bash
# 案例1 : ok是否等于ok
[ ok ok ] echo 案例1相等 || echo 案例1不相等# 案例2 : 23是否大于等于22
[ 23 -ge 22 ] echo 案例223≥22 || echo 案例22322# 案例3 : /root/shcode/aaa.txt目录中的文件是否存在
[ -f /root/shcode/aaa.txt ] echo 案例3/root/shcode/aaa.txt存在 || echo 案例3/root/shcode/aaa.txt不存在
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh ifdemo.sh
案例1相等
案例223≥22
案例3/root/shcode/aaa.txt不存在
[rootCentOS76 myshcode]# 17.3.3 read读取控制台输入
本小节介绍Shell脚本如何使用read读取用户实时输入的参数。下面是基本语法
# 基本语法-read
read 选项 参数# 常用选项-read
-p 指定读取值时的提示符
-t 指定读取值时等待的时间(秒)。如果指定时间内没有输入就直接跳过。# 常用参数-read
变量名 指定读取值的变量名下面展示两个应用实例/home/myshcode/readDemo.sh 【案例1】读取控制台输入一个NUM1值。 【案例2】读取控制台输入一个NUM2值10秒内输入。
# 编写代码文件
[rootCentOS76 myshcode]# vim readDemo.sh
####################################
# 输入以下代码
#!/bin/bash
# 案例1读取控制台输入一个NUM1值。
read -p 请输入NUM1 NUM1
echo 已输入NUM1$NUM1
# 案例2读取控制台输入一个NUM2值10秒内输入。
read -t 10 -p 请在10s内输入NUM2 NUM2
[ $NUM2 ] echo 已输入NUM2$NUM2 || echo NUM2未输入
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh readDemo.sh
请输入NUM110
已输入NUM110
请在10s内输入NUM210
已输入NUM210
[rootCentOS76 myshcode]# sh readDemo.sh
请输入NUM110
已输入NUM110
请在10s内输入NUM2NUM2未输入17.4 Shell流程控制
17.4.1 if判断
前面在介绍“条件判断”时首先介绍了三元运算符的语法本节我们就继续介绍真正的if-else语句。
# 基本语法-if判断
# 1.单分支结构
if [ 条件判断式 ]
then#代码
fi# 2.多分支结构
if [ 条件判断式 ]
then#代码
elif [ 条件判断式 ]
then#代码
else#代码
fi# 注条件判断式左右两侧一定要有空格下面展示一个应用实例 【案例1】请编写一个/home/myshcode/ifScore.sh若输入的参数≥60则输出“及格了”若60则输出“不及格”。
# 编写代码文件
[rootCentOS76 myshcode]# vim ifScore.sh
####################################
# 输入以下代码
#!/bin/bash
if [ $1 -ge 60 ] [ $1 -le 100 ]
thenecho 及格了
elif [ $1 -lt 60 ] [ $1 -ge 0 ]
thenecho 不及格
elseecho 分数不在范围内
fi
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh ifScore.sh 101
分数不在范围内
[rootCentOS76 myshcode]# sh ifScore.sh -20
分数不在范围内
[rootCentOS76 myshcode]# sh ifScore.sh 70
及格了
[rootCentOS76 myshcode]# sh ifScore.sh 40
不及格17.4.2 case语句
那当需要对某一个变量进行多次判断时显然使用多分支if-else就不太美观于是也就需要介绍一下case语法。
# 基本语法-case语句
case $变量名 in
值1)#若变量为值1执行此代码
;;
值2)#若变量为值1执行此代码
;;
..省略其他分支...
*)#若变量为其他值则执行此代码
;;
esac # 注意这个也是case的反写下面展示一个应用实例 【案例1】编写/home/myshcode/caseDemo.sh判断命令行参数若为1则输出“周一”若为2则输出“周二”其它情况输出“other”。
# 编写代码文件
[rootCentOS76 myshcode]# vim caseDemo.sh
####################################
# 输入以下代码
#!/bin/bash
case $1 in
1) echo 周一 ;;
2) echo 周二 ;;
*) echo other ;;
esac
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh caseDemo.sh
other
[rootCentOS76 myshcode]# sh caseDemo.sh 1
周一
[rootCentOS76 myshcode]# sh caseDemo.sh 2
周二
[rootCentOS76 myshcode]# sh caseDemo.sh 3
other17.4.3 for循环
介绍完条件判断的一系列语法显然也得来看看循环语法for。
# 基本语法1-for循环
for 变量 in 值1 值2 值3...
do#程序代码
done# 基本语法2-for循环
for ((初始值; 循环控制条件; 变量变化)) #注意每个分号后都有一个空格
do#程序代码
done下面展示两个应用实例/home/myshcode/forDemo.sh 【案例1】打印命令行输入的参数注意这里可以看出$*和$的区别。 【案例2】从1加到100的值输出显示。
# 编写代码文件
[rootCentOS76 myshcode]# vim forDemo.sh
####################################
# 输入以下代码
#!/bin/bash
# 案例1打印命令行输入的参数
# $*将输入参数看作一个整体所以只输出一句话
for i in $*
doecho 使用\$*$i
done
# $将输入参数分别看待所以每个参数都输出一行
for i in $
doecho 使用\$$i
done# 案例2从1加到100的值输出显示
SUM0
for((i1; i100; i))
doSUM$[$SUM$i]
done
echo 0~100的和$SUM
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh forDemo.sh 10 20 30 40
使用$*10 20 30 40
使用$10
使用$20
使用$30
使用$40
0~100的和505017.4.4 while循环
那介绍了for循环肯定也得介绍一下while循环。
# 基本语法-while循环
while [ 条件判断式 ] # 注意while和[]之间有空格[]内的条件判断式两侧也有空格
do#程序代码
done下面展示一个应用实例 【案例1】创建/home/myshcode/whileDemo.sh从命令行输入一个数n计算从1…n的值是多少
# 编写代码文件
[rootCentOS76 myshcode]# vim whileDemo.sh
####################################
# 输入以下代码
#!/bin/bash
SUM0
i1
while [ $i -le $1 ]
doSUM$[$SUM$i]i$[$i1]
done
echo 12...$1的和$SUM
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh whileDemo.sh 10
12...10的和55
[rootCentOS76 myshcode]# sh whileDemo.sh 100
12...100的和505017.5 函数
shell编程和其它编程语言一样有系统函数也可以自定义函数。下面来依次介绍。
17.5.1 系统函数
本节就介绍两个常用的系统函数。
# 基本语法1-basename
basename [pathname/string] [suffix] # 返回pathname/string最后的文件名不包括最后一个/
# suffix为后缀如果suffix被指定(如.txt)则也会再将后缀删除。
# 常用于获取文件名。# 基本语法2-dirname
dirname 文件绝对路径 # 去除绝对路径最后的文件名返回剩下的目录部分
# 常用于返回路径部分。下面展示两个应用实例
# 【案例1】返回/home/aaa/test.txt的test.txt部分。
[rootCentOS76 myshcode]# basename /home/aaa/test.txt
test.txt
[rootCentOS76 myshcode]# basename /home/aaa/test.txt .txt
test# 【案例2】返回/home/aaa/test.txt的/home/aaa。
[rootCentOS76 myshcode]# dirname /home/aaa/test.txt
/home/aaa17.5.2 自定义函数
自定义函数比较重要用的也比较多。下面是自定义函数的基本语法。
# 基本语法-自定义函数
# 1. 函数定义
function funname(){#程序代码[return int;] #返回值
}
# 2. 函数调用
funname [值]下面展示一个应用实例 【案例1】使用户输入两个参数然后自定义函数getSum计算这两个参数的和。
# 编写代码文件
[rootCentOS76 myshcode]# vim FunDemo.sh
####################################
# 输入以下代码
#!/bin/bash
# 定义求和函数getSum
function getSum(){SUM$[$n1$n2]echo $n1$n2$SUM
}read -p 请输入两个数(空格隔开) n1 n2 #读取用户输入
getSum n1 n2 #计算和
####################################
# 下面是运行结果
[rootCentOS76 myshcode]# sh FunDemo.sh
请输入两个数(空格隔开)10 20
10203017.6 Shell编程综合案例
本大节就根据前面所介绍的内容来完成一个Shell编程的综合案例——定时备份数据库。首先给出需求 每天凌晨2:30(crond)备份数据库mydata到/data/backup/db。备份开始和备份结束能够给出相应的提示信息。备份后的文件要求以备份时间为文件名并打包成.tar.gz的形式比如2021-03-12_230201.tar.gz。在备份的同时检查是否有10天前备份的数据库文件如果有就将其删除。 并且注意数据库已经准备好了具体过程见第16章“16.5 安装mysql5.7”的最后一个步骤。下面是当时的内容回放 【步骤5】重新登录并玩一玩mysql。比如创建一个表格之类的。 mysql -u root -p # 登录mysql
# 注意这里要输入新设置的密码rootroot
show databases; # 显示当前数据库
create database mydata; # 创建新的数据库
use mydata; # 使用该数据库
create table myorder(id int, name varchar(32)); # 创建表格
select * from myorder; # 显示表格信息
insert into myorder values(100, dog); # 添加表格数据
select * from myorder; # 显示表格信息
quit # 退出mysql#mermaid-svg-bq2uVsEwrk8rFY9v {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-bq2uVsEwrk8rFY9v .error-icon{fill:#552222;}#mermaid-svg-bq2uVsEwrk8rFY9v .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bq2uVsEwrk8rFY9v .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-bq2uVsEwrk8rFY9v .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bq2uVsEwrk8rFY9v .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bq2uVsEwrk8rFY9v .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bq2uVsEwrk8rFY9v .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bq2uVsEwrk8rFY9v .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bq2uVsEwrk8rFY9v .marker.cross{stroke:#333333;}#mermaid-svg-bq2uVsEwrk8rFY9v svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bq2uVsEwrk8rFY9v .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-bq2uVsEwrk8rFY9v .cluster-label text{fill:#333;}#mermaid-svg-bq2uVsEwrk8rFY9v .cluster-label span{color:#333;}#mermaid-svg-bq2uVsEwrk8rFY9v .label text,#mermaid-svg-bq2uVsEwrk8rFY9v span{fill:#333;color:#333;}#mermaid-svg-bq2uVsEwrk8rFY9v .node rect,#mermaid-svg-bq2uVsEwrk8rFY9v .node circle,#mermaid-svg-bq2uVsEwrk8rFY9v .node ellipse,#mermaid-svg-bq2uVsEwrk8rFY9v .node polygon,#mermaid-svg-bq2uVsEwrk8rFY9v .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bq2uVsEwrk8rFY9v .node .label{text-align:center;}#mermaid-svg-bq2uVsEwrk8rFY9v .node.clickable{cursor:pointer;}#mermaid-svg-bq2uVsEwrk8rFY9v .arrowheadPath{fill:#333333;}#mermaid-svg-bq2uVsEwrk8rFY9v .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bq2uVsEwrk8rFY9v .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bq2uVsEwrk8rFY9v .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-bq2uVsEwrk8rFY9v .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-bq2uVsEwrk8rFY9v .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bq2uVsEwrk8rFY9v .cluster text{fill:#333;}#mermaid-svg-bq2uVsEwrk8rFY9v .cluster span{color:#333;}#mermaid-svg-bq2uVsEwrk8rFY9v div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bq2uVsEwrk8rFY9v :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} crond定时调度任务每天2:30调用脚本 /usr/sbin/mysql_db_backup.sh任务1备份数据库任务2给出提示信息任务3打包备份数据任务4删除10天前的文件-基于文件名 数据库mydata-myroder 图17-3 数据库备份步骤 进行备份的思路如上图所示首先创建/usr/sbin/mysql_db_backup.sh文件完成单次备份任务然后在将该文件添加到crond定时调度中即可完成每天定时的数据库备份。将备份脚本放在/usr/sbin目录下的原因是这个目录只有root用户执行的权限并且后续也会使用root用户来设置定时任务。
下面分别给出/usr/sbin/mysql_db_backup.sh文件内容、使用crontab添加定时任务
/usr/sbin/mysql_db_backup.sh
#!/bin/bash
#下面是基本信息
#备份目录
BACKUP/data/backup/db
#获取当前的时间
DATETIME$(date %Y-%m-%d_%H%M%S)
echo $DATETIME
#数据库的地址
HOSTlocalhost
#数据库的用户名
DB_USERroot
#数据库密码
DB_PWrootroot
#备份的数据库名
DATABASEmydata#创建备份目录若不存在就创建
[ ! -d ${BACKUP}/${DATETIME} ] mkdir -p ${BACKUP}/${DATETIME}#备份数据库
mysqldump -u${DB_USER} -p${DB_PW} --host${HOST} -q -R --databases ${DATABASE} | gzip ${BACKUP}/${DATETIME}/$DATETIME.sql.gz#将整个备份目录打包成tar.gz
cd ${BACKUP} #要打包的文件名若为绝对路径就会报错所以这一步cd很重要
tar -zcvf $DATETIME.tar.gz ${DATETIME}
#再删除这个备份目录
rm -rf ${BACKUP}/${DATETIME}#删除10天前的备份文件
find ${BACKUP} -atime 10 -name *.tar.gz -exec rm -rf {} \;
echo 备份数据库${DATABASE}成功~添加定时任务
# 1. 添加定时任务
[rootCentOS76 /]# crontab -e
no crontab for root - using an empty one
####################################
# 按照vim编辑器的格式输入以下命令并保存
30 2 * * * /usr/sbin/mysql_db_backup.sh
####################################
crontab: installing new crontab# 2. 查看定时任务是否添加成功
[rootCentOS76 /]# crontab -l
30 2 * * * /usr/sbin/mysql_db_backup.sh《鸟哥的Linux私房菜 基础学习篇 第四版》 ↩︎ 《鸟哥的Linux私房菜 服务器架设篇 第三版》 ↩︎ 《韩顺平_2021图解Linux全面升级》 ↩︎