- 学习视频来自于B站【小白入门 通俗易懂】2021韩顺平 一周学会Linux。
- 可能会用到的资料有如下所示,下载链接见文末:
- 《鸟哥的Linux私房菜 基础学习篇 第四版》1
- 《鸟哥的Linux私房菜 服务器架设篇 第三版》2
- 《韩顺平_2021图解Linux全面升级》3
Shell才是Linux的精华,Shell几乎是IT企业必须使用的运维自动化编程语言,特别是在运维工作中的服务监控、业务快速部署、服务启动停止、数据备份及处理、日志分析等环节里,shell是不可缺的。工作角度来讲,学习 Shell 是为了提高我们自己工作效率,提高产出,让我们在更少的时间完成更多的事情。比如下面给出几个需要Shell开发的场景中:
- Linux运维工程师在进行服务器集群管理时,需要编写Shell程序来进行服务器管理。
- 对于JavaEE和Python程序员来说,工作的需要,你的老大会要求你编写一些Shell脚本进行程序或者是服务器的维护,比如编写一个定时备份数据库的脚本。
- 对于大数据程序员来说,需要编写Shell程序来管理集群。
更多可以查看知乎文章“Shell 编程入门”。
对于初学者来说不必学的太复杂,只要熟练掌握基本语法,并且能看懂别人的Shell脚本即可。
Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。如下图所示:
Linux系统中不止一个Shell,常见的有bash(ba shell)、tcsh(tc shell)、csh(c shell)等,在国内常用的是bash。
首先来说一下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
[root@CentOS76 ~]# mkdir /root/myshcode # 创建一个文件夹专门用于存放shell脚本
[root@CentOS76 ~]# cd /root/myshcode/
[root@CentOS76 myshcode]# vim hello.sh
######################################
# 输入以下代码,注意第一行不是注释:
#!/bin/bash
echo "hello,shell!"
######################################
# 2. 执行方式1
[root@CentOS76 myshcode]# sh hello.sh
hello,shell!
# 3. 执行方式2
[root@CentOS76 myshcode]# ./hello.sh
-bash: ./hello.sh: 权限不够
[root@CentOS76 myshcode]# chmod u+x hello.sh
[root@CentOS76 myshcode]# ll
总用量 4
-rwxr--r--. 1 root root 32 7月 29 10:41 hello.sh
[root@CentOS76 myshcode]# ./hello.sh
hello,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。
# A=`date`就是将当前时间(比如“2023年 08月 22日 星期二 12:03:44 CST”)赋给了A。
# A=date就是将单词date赋值给变量A。
A=$(指令) # 等价于 A=`指令`
当然,Shell编程中对于自定义变量的名称也有一些约定俗成的规定:
- 变量名称可以由字母、数字和下划线组成,但是不能以数字开头。
5A=200
(不允许!)- 变量名称一般习惯为大写,但是小写也可以运行。
- 定义变量时等号两侧不能有空格(强制规定)。
下面创建/home/myshcode/var.sh
,并展示四个应用案例:
# 创建源代码文件
[root@CentOS76 myshcode]# vim var.sh
########################################
# 下面是var.sh中的源代码,注意下面第一行不是注释
#!/bin/bash
# 案例1:定义变量A
A=30
echo A=$A
echo "A=$A"
# 案例2:撤销变量A
unset A
echo "A=$A"
# 案例3:声明静态的变量B=2,不能unset
readonly B=2
echo "B=$B"
unset B
# 案例4:将指令返回的结果赋值给变量
C=`date`
D=$(date)
echo C=$C
echo D=$D
########################################
# 下面是运行结果
[root@CentOS76 myshcode]# sh var.sh
A=30
A=30
A=
B=2
var.sh: 第 14 行:unset: B: 无法反设定: 只读 variable
C=2023年 07月 29日 星期六 11:18:07 CST
D=2023年 07月 29日 星期六 11:18:07 CST
既然前面提到了环境变量,那么本节就来介绍一下如何添加一个新的环境变量。全局环境变量信息一般都存储在/etc/profile
中,于是在Linux任意目录下的一个Shell脚本都可以调用这个文件中的环境变量(如上图所示)。设置环境变量的语法如下:
# 基本语法-设置环境变量
## 在/etc/profile文件中设置
export 变量名=变量值 # 将shell变量输出为环境变量/全局变量
## 在终端窗口设置
source 配置文件 # 让修改后的配置信息立即生效!!
echo $变量名 # 查询环境变量的值
下面展示一个应用案例:
【案例1】在/etc/profile文件中定义TOMCAT_HOME的安装路径/opt/tomcat为环境变量,然后分别在终端、脚本/home/myshcode/a.sh查看环境变量TOMCAT_HOME的值。
# 1. 添加环境变量
[root@CentOS76 myshcode]# vim /etc/profile
##########################################
# 在文件末尾添加下面一行:
export TOMCAT_HOME=/opt/tomcat
##########################################
# 2. 在设置生效前后查看环境变量的值
[root@CentOS76 myshcode]# echo $TOMCAT_HOME
[root@CentOS76 myshcode]# source /etc/profile
[root@CentOS76 myshcode]# echo $TOMCAT_HOME
/opt/tomcat
# 3. 编写/home/myshcode/a.sh查看环境变量
[root@CentOS76 myshcode]# vim a.sh
####################################
# 编写如下两行代码
#!/bin/bash
echo TOMCAT+HOME=$TOMCAT_HOME
####################################
[root@CentOS76 myshcode]# sh a.sh
TOMCAT+HOME=/opt/tomcat
那在平常编程过程中,常常会遇到“形式参数”这个概念。类似的,显然有时候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,在脚本中获取到命令行的长、宽、高三个参数信息并输出。
# 编写代码文件
[root@CentOS76 myshcode]# vim box.sh
####################################
# 输入以下代码:
#!/bin/bash
echo "长=$1,宽=$2,高=$3"
echo "长宽高=$*"
echo "长宽高=$@"
echo "输入的参数个数:$#"
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh box.sh 3 4 5
长=3,宽=4,高=5
长宽高=3 4 5
长宽高=3 4 5
输入的参数个数:3
“预定义变量”就是shell设计者事先已经定义好的变量,可以直接在shelI脚本中使用。这个用的并不是很多,所以只是简单介绍一下。
# 常见的预定义变量
$$ # 当前进程的进程号(PID)
$! # 后台运行的最后一个进程的进程号(PID)
$? # 最后一次执行的命令的返回状态。0(正确执行)/非0(不正确执行)
下面展示一个应用实例:
【案例1】在一个shell脚本/home/myshcode/preVar.sh中简单使用一下预定义变量。
# 编写代码文件
[root@CentOS76 myshcode]# vim preVar.sh
####################################
# 输入以下代码:
#!/bin/bash
echo "当前执行的进程ID=$$"
# 以后台方式运行一个脚本,并获取它的进程号
/root/myshcode/a.sh & #&表示取地址
echo "最后一个后台方式运行的进程ID=$!"
echo "执行的结果是=$?"
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh preVar.sh
当前执行的进程ID=28344
最后一个后台方式运行的进程ID=28345
执行的结果是=0
[root@CentOS76 myshcode]# TOMCAT+HOME=/opt/tomcat
^C
[root@CentOS76 myshcode]#
# 注:因为在脚本里面运行了另一个脚本,所以卡住了,ctrl+c退出。
本小节学习如何在shell中进行各种运算操作,也就是加减乘除:
# 基本语法-运算符
$((运算式)) # 方式1,太麻烦不推荐
$[运算式] # 方式2,推荐
expr m + n # 方式3,注意expr运算符间要有空格;如果希望将expr的结果赋给某个变量,使用``
# 运算符方式3-expr
+ 加
- 减
\* 乘
/ 除
% 取余
下面展示两个应用实例:
【案例1】计算(2+3)x4的值。
【案例2】计算命令行的两个整数参数的和。
# 编写代码文件
[root@CentOS76 myshcode]# vim oper.sh
####################################
# 输入以下代码:
#!/bin/bash
# 案例1:计算(2+3)x4的值
# 方式1:$(())
RES1=$(((2+3)*4))
echo "res1=$RES1"
# 方式2:$[]
RES2=$[(2+3)*4]
echo "res2=$RES2"
# 方式3:使用expr
TEMP=`expr 2 + 3`
RES3=`expr $TEMP \* 4`
echo "temp=$TEMP, res3=$RES3"
# 案例2:请求出命令行的两个参数[整数]的和
SUM=$[$1+$2]
echo "sum=$SUM"
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh oper.sh 30 50
res1=20
res2=20
temp=5, res3=20
sum=80
本小节来介绍Shell编程中条件判断语法,以及三元运算符(一种简便的if-else
形式)。
# 基本语法-判断语句
[ condition ] # 注意condition前后要有空格。
# condition非空返回true,可使用$?验证(0为true,>1为false)。
# 应用实例-判断语句
[ hello ] # 返回true
[ ] # 返回false,注意空格!
[ condition ] && 语句1 || 语句2 # 三元运算符,条件为真执行语句1,否则执行语句2
# 常用判断条件
# 1.字符串比较
= 字符串比较
# 2.两个整数的比较
-lt 小于,little
-le 小于等于,little+equal
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于
# 3.按照文件权限进行判断
-r 有读的权限
-w 有写的权限
-x 有执行的权限
# 4.按照文件类型进行判断
-f 文件存在并且是一个常规的文件
-e 文件存在
-d 文件存在并是一个目录
下面站是三个应用实例:
【案例1】“ok"是否等于"ok”。
【案例2】23是否大于等于22。
【案例3】/root/shcode/aaa.txt目录中的文件是否存在。
# 编写代码文件
[root@CentOS76 myshcode]# vim ifdemo.sh
####################################
# 输入以下代码:
#!/bin/bash
# 案例1 : "ok"是否等于"ok"
[ "ok" = "ok" ] && echo "案例1:相等" || echo "案例1:不相等"
# 案例2 : 23是否大于等于22
[ 23 -ge 22 ] && echo "案例2:23≥22" || echo "案例2:23<22"
# 案例3 : /root/shcode/aaa.txt目录中的文件是否存在
[ -f /root/shcode/aaa.txt ] && echo "案例3:/root/shcode/aaa.txt存在" || echo "案例3:/root/shcode/aaa.txt不存在"
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh ifdemo.sh
案例1:相等
案例2:23≥22
案例3:/root/shcode/aaa.txt不存在
[root@CentOS76 myshcode]#
本小节介绍Shell脚本如何使用read
读取用户实时输入的参数。下面是基本语法:
# 基本语法-read
read 选项 参数
# 常用选项-read
-p 指定读取值时的提示符
-t 指定读取值时等待的时间(秒)。如果指定时间内没有输入,就直接跳过。
# 常用参数-read
变量名 指定读取值的变量名
下面展示两个应用实例/home/myshcode/readDemo.sh
:
【案例1】读取控制台输入一个NUM1值。
【案例2】读取控制台输入一个NUM2值,10秒内输入。
# 编写代码文件
[root@CentOS76 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未输入!"
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh readDemo.sh
请输入NUM1=10
已输入NUM1=10
请在10s内输入NUM2=10
已输入NUM2=10
[root@CentOS76 myshcode]# sh readDemo.sh
请输入NUM1=10
已输入NUM1=10
请在10s内输入NUM2=NUM2未输入!
前面在介绍“条件判断”时首先介绍了三元运算符的语法,本节我们就继续介绍真正的if-else
语句。
# 基本语法-if判断
# 1.单分支结构
if [ 条件判断式 ]
then
#代码
fi
# 2.多分支结构
if [ 条件判断式 ]
then
#代码
elif [ 条件判断式 ]
then
#代码
else
#代码
fi
# 注:条件判断式左右两侧一定要有空格!!
下面展示一个应用实例:
【案例1】请编写一个/home/myshcode/ifScore.sh
,若输入的参数≥60则输出“及格了”;若<60则输出“不及格”。
# 编写代码文件
[root@CentOS76 myshcode]# vim ifScore.sh
####################################
# 输入以下代码:
#!/bin/bash
if [ $1 -ge 60 ] && [ $1 -le 100 ]
then
echo "及格了!"
elif [ $1 -lt 60 ] && [ $1 -ge 0 ]
then
echo "不及格!"
else
echo "分数不在范围内!"
fi
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh ifScore.sh 101
分数不在范围内!
[root@CentOS76 myshcode]# sh ifScore.sh -20
分数不在范围内!
[root@CentOS76 myshcode]# sh ifScore.sh 70
及格了!
[root@CentOS76 myshcode]# sh ifScore.sh 40
不及格!
那当需要对某一个变量进行多次判断时,显然使用多分支if-else
就不太美观,于是也就需要介绍一下case
语法。
# 基本语法-case语句
case $变量名 in
"值1")
#若变量为值1,执行此代码
;;
"值2")
#若变量为值1,执行此代码
;;
..省略其他分支...
*)
#若变量为其他值,则执行此代码
;;
esac # 注意这个也是case的反写
下面展示一个应用实例:
【案例1】编写/home/myshcode/caseDemo.sh
判断命令行参数,若为1则输出“周一”;若为2则输出“周二”;其它情况输出“other”。
# 编写代码文件
[root@CentOS76 myshcode]# vim caseDemo.sh
####################################
# 输入以下代码:
#!/bin/bash
case $1 in
"1") echo "周一" ;;
"2") echo "周二" ;;
*) echo "other" ;;
esac
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh caseDemo.sh
other
[root@CentOS76 myshcode]# sh caseDemo.sh 1
周一
[root@CentOS76 myshcode]# sh caseDemo.sh 2
周二
[root@CentOS76 myshcode]# sh caseDemo.sh 3
other
介绍完条件判断的一系列语法,显然也得来看看循环语法for
。
# 基本语法1-for循环
for 变量 in 值1 值2 值3...
do
#程序代码
done
# 基本语法2-for循环
for ((初始值; 循环控制条件; 变量变化)) #注意每个分号后都有一个空格!
do
#程序代码
done
下面展示两个应用实例/home/myshcode/forDemo.sh
:
【案例1】打印命令行输入的参数(注意这里可以看出$*
和$@
的区别)。
【案例2】从1加到100的值输出显示。
# 编写代码文件
[root@CentOS76 myshcode]# vim forDemo.sh
####################################
# 输入以下代码:
#!/bin/bash
# 案例1:打印命令行输入的参数
# $*将输入参数看作一个整体,所以只输出一句话
for i in "$*"
do
echo "使用\$*:$i"
done
# $@将输入参数分别看待,所以每个参数都输出一行
for i in "$@"
do
echo "使用\$@:$i"
done
# 案例2:从1加到100的值输出显示
SUM=0
for((i=1; i<=100; i++))
do
SUM=$[$SUM+$i]
done
echo "0~100的和:$SUM"
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh forDemo.sh 10 20 30 40
使用$*:10 20 30 40
使用$@:10
使用$@:20
使用$@:30
使用$@:40
0~100的和:5050
那介绍了for
循环,肯定也得介绍一下while
循环。
# 基本语法-while循环
while [ 条件判断式 ] # 注意while和[]之间有空格,[]内的条件判断式两侧也有空格!
do
#程序代码
done
下面展示一个应用实例:
【案例1】创建/home/myshcode/whileDemo.sh
,从命令行输入一个数n,计算从1+…+n的值是多少?
# 编写代码文件
[root@CentOS76 myshcode]# vim whileDemo.sh
####################################
# 输入以下代码:
#!/bin/bash
SUM=0
i=1
while [ $i -le $1 ]
do
SUM=$[$SUM+$i]
i=$[$i+1]
done
echo "1+2+...+$1的和:$SUM"
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh whileDemo.sh 10
1+2+...+10的和:55
[root@CentOS76 myshcode]# sh whileDemo.sh 100
1+2+...+100的和:5050
shell编程和其它编程语言一样,有系统函数,也可以自定义函数。下面来依次介绍。
本节就介绍两个常用的系统函数。
# 基本语法1-basename
basename [pathname/string] [suffix] # 返回pathname/string最后的文件名,不包括最后一个'/'
# suffix为后缀,如果suffix被指定(如'.txt'),则也会再将后缀删除。
# 常用于获取文件名。
# 基本语法2-dirname
dirname 文件绝对路径 # 去除绝对路径最后的文件名,返回剩下的目录部分
# 常用于返回路径部分。
下面展示两个应用实例:
# 【案例1】返回/home/aaa/test.txt的"test.txt"部分。
[root@CentOS76 myshcode]# basename /home/aaa/test.txt
test.txt
[root@CentOS76 myshcode]# basename /home/aaa/test.txt .txt
test
# 【案例2】返回/home/aaa/test.txt的/home/aaa。
[root@CentOS76 myshcode]# dirname /home/aaa/test.txt
/home/aaa
自定义函数比较重要,用的也比较多。下面是自定义函数的基本语法。
# 基本语法-自定义函数
# 1. 函数定义
function funname(){
#程序代码
[return int;] #返回值
}
# 2. 函数调用
funname [值]
下面展示一个应用实例:
【案例1】使用户输入两个参数,然后自定义函数getSum计算这两个参数的和。
# 编写代码文件
[root@CentOS76 myshcode]# vim FunDemo.sh
####################################
# 输入以下代码:
#!/bin/bash
# 定义求和函数getSum
function getSum(){
SUM=$[$n1+$n2]
echo "$n1+$n2=$SUM"
}
read -p "请输入两个数(空格隔开):" n1 n2 #读取用户输入
getSum n1 n2 #计算和
####################################
# 下面是运行结果:
[root@CentOS76 myshcode]# sh FunDemo.sh
请输入两个数(空格隔开):10 20
10+20=30
本大节就根据前面所介绍的内容,来完成一个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
进行备份的思路如上图所示,首先创建/usr/sbin/mysql_db_backup.sh
文件完成单次备份任务,然后在将该文件添加到crond
定时调度中,即可完成每天定时的数据库备份。将备份脚本放在/usr/sbin目录下的原因是这个目录只有root用户执行的权限,并且后续也会使用root用户来设置定时任务。
下面分别给出/usr/sbin/mysql_db_backup.sh
文件内容、使用crontab
添加定时任务:
#!/bin/bash
#下面是基本信息
#备份目录
BACKUP=/data/backup/db
#获取当前的时间
DATETIME=$(date +%Y-%m-%d_%H%M%S)
echo $DATETIME
#数据库的地址
HOST=localhost
#数据库的用户名
DB_USER=root
#数据库密码
DB_PW=rootroot
#备份的数据库名
DATABASE=mydata
#创建备份目录,若不存在就创建
[ ! -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. 添加定时任务
[root@CentOS76 /]# crontab -e
no crontab for root - using an empty one
####################################
# 按照vim编辑器的格式,输入以下命令并保存:
30 2 * * * /usr/sbin/mysql_db_backup.sh
####################################
crontab: installing new crontab
# 2. 查看定时任务是否添加成功
[root@CentOS76 /]# crontab -l
30 2 * * * /usr/sbin/mysql_db_backup.sh
《鸟哥的Linux私房菜 基础学习篇 第四版》 ↩︎
《鸟哥的Linux私房菜 服务器架设篇 第三版》 ↩︎
《韩顺平_2021图解Linux全面升级》 ↩︎