Linux——Shell编程

XShell编程

本来小黄在学习Linux的路上是想跳过Shell编程的,后来听老韩讲对于Java程序员来说,可能在工作的时候,会要求编写一个shell脚本来对服务器进行维护,比如定时备份数据库的脚本。那还是得了解一下,至少简单的会写会看!!!

什么是Shell?

shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统及程序,用户可以用shell来启动、挂起、停止甚至是编写一些程序。

就像我们平时利用xshell、finalshell等工具,执行的语句会通过命令行解释器交给Linux内核来处理。

在这里插入图片描述

helloworld

所有新的语言学习的过程中,第一项永远都是向世界呐喊,我们学习Shell语言也不例外

创建文件

[root@yellowstarEdu01 ~]# vim hello.sh

编写脚本,shell语言要以#!/bin/bash开头

#!/bin/bash
echo "hello,world!"  # echo是输出,类似于sout

直接使用vim创建的文件是没有执行权限的,可以用以下两种方式解决

# 方案一:使用sh命令
[root@yellowstarEdu01 ~]# sh hello.sh 
hello,world!
# 方案二:添加执行权限
[root@yellowstarEdu01 ~]# chmod u+x hello.sh
-rwxr--r--. 1 root root   32 28 09:08 hello.sh
[root@yellowstarEdu01 ~]# ./hello.sh 
hello,world!

shell变量

基础变量

Linux中Shell变量分为系统变量和用户自定义变量

系统变量如: H O M E , HOME, HOMEPWD等

[root@yellowstarEdu01 shcode]# echo $PWD
/root/shcode

这里我们重点学习的是用户自定义变量。

基本语法

  • 定义变量:变量名=值(注意等号两边不能有空格)
  • 撤销变量:unset 变量名
  • 声明静态:readonly 变量名=值

测试

#!/bin/bash
# 定义变量A
A=100
echo A=$A
# 撤销变量A
unset A
echo A=$A
# 声明静态变量B
readonly B=200
echo B=$B
# 静态变量不能unset
unset B

[root@yellowstarEdu01 shcode]# ./test.sh 
A=100
A=
B=200
./test.sh: 第 12 行:unset: B: 无法反设定: 只读 variable

定义变量的规则

  • 变量名由字母、数字、下划线组成,但是不能以数字开头
  • 等号两侧不能有空格
  • 变量名建议大写

将命令返回值赋给变量

C=`date`  #反引号,运行里面的命令,并将结果返回给C
D=$(date) # $()等价于反引号
echo C=$C
echo D=$D

[root@yellowstarEdu01 shcode]# ./test.sh 
C=2022年 02月 08日 星期二 10:53:52 CST
D=2022年 02月 08日 星期二 10:53:52 CST

设置环境变量

环境变量,我们可以当作全局变量来使用,可以作用于所有的shell脚本中

基本语法

  • export 变量名=变量值 (将shell变量输出为环境变量)
  • source 配置文件 (让修改后的配置信息立即生效)
  • echo $变量名 (查询环境变量的值)

测试

  1. 在/etc/profile文件中定义TOMCAT_HOME环境变量

    [root@yellowstarEdu01 shcode]# vim /etc/profile
    # 在最后添加以下语句
    export TOMCAT_HOME=/opt/tomcat
    
  2. 查看环境变量TOMCAT_HOME的值

    # 直接查询不显示结果,需要先source
    [root@yellowstarEdu01 shcode]# echo $TOMCAT_HOME  
    
    [root@yellowstarEdu01 shcode]# source /etc/profile
    [root@yellowstarEdu01 shcode]# echo $TOMCAT_HOME
    /opt/tomcat
    
  3. 在另一个shell程序中使用TOMCAT_HOME

    #!/bin/bash
    A=$TOMCAT_HOME
    echo A=$A
    
    [root@yellowstarEdu01 shcode]# ./tomcat.sh 
    A=/opt/tomcat
    

位置参数变量

当我们执行一个shell脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数

比如 :./myshell.sh 100 200,这个就是一个执行shell的命令行

基本语法

  • $n:n为数字,$0代表命令本身,$1- 9 代 表 第 一 到 第 九 个 参 数 , 十 以 上 的 参 数 用 大 括 号 , 9代表第一到第九个参数,十以上的参数用大括号, 9{10}
  • $*:代表命令行中所有的参数,把所有的参数看成一个整体
  • $@:代表命令行中所有的参数,把每个参数区分对待
  • $#:命令行中所有参数的个数

测试

#!/bin/bash
echo 0=$0 1=$1 2=$2
echo 所有的参数=$*
echo $@
echo 参数的个数为=$#

[root@yellowstarEdu01 shcode]# ./position.sh 100 200
0=./position.sh 1=100 2=200
所有的参数=100 200
100 200
参数的个数为=2

预定义变量

shell设计者事先已经定义好的变量,可以直接在shell脚本中使用

基本语法

  • $$:当前进程的进程ID
  • $!:后台运行的最后一个进程的ID
  • $?:最后一次执行的命令的返回状态,值为0,证明上一个命令正确执行

测试

#!/bin/bash
echo 当前进程的PID=$$
# 以后台方式运行一个脚本
/root/shcode/tomcat.sh &
echo 最后一个脚本的PID=$!
echo 执行的脚本返回值=$?

[root@yellowstarEdu01 shcode]# ./preVar.sh 
当前进程的PID=114724
最后一个脚本的PID=114725
执行的脚本返回值=0
[root@yellowstarEdu01 shcode]# A=/opt/tomcat

运算以及流程控制

运算符

基本语法

  • ( ( 运 算 式 ) ) 或 ((运算式)) 或 (())[运算式] 或 expr m + n
  • 注意expr运算符之间要有空格
  • expr \* , /%代表乘,除,取余

测试

#!/bin/bash
# 计算(2+3)*4的值
expr $[2+3] \* 4
# 命令行输入两个整数,求和
echo $[$1+$2]

[root@yellowstarEdu01 shcode]# ./sum.sh 100 20
20
120

条件判断

常用判断条件

  • =:字符串比较
  • 整数比较
    • -lt:小于
    • -le:小于等于
    • -eq:等于
    • -gt:大于
    • -ge:大于等于
    • -ne:不等于
  • 按照文件权限进行判断
    • -r:有读的权限
    • -w:有写的权限
    • -x:有执行的权限
  • 按照文件类型进行判断
    • -f:文件存在并且是一个文件
    • -e:文件存在
    • -d:文件存在并是一个目录

基本语法

[ condition ] 注意:condition前后必须要有空格

condition非空返回 true,空则返回false

if [ 条件判断式 ] 
then
	代码
fi #if语句结束

测试

#!/bin/bash
# 判断字符串ok是否等于ok
if [ "ok"="ok" ]
then
    echo yes
fi
# 判断23是否大于等于22
if [ 23 -ge 22 ]
then
    echo 大于
fi
# /root/shcode/aaa.txt文件是否存在
if [ -f /root/shcode/aaa.txt ]
then
    echo 文件存在
fi

[root@yellowstarEdu01 shcode]# ./ifdemo.sh 
yes
大于
# 因为文件不存在,所以没有输出

多分支

相当于if…else…

if [ 条件判断式 ] 
then
	代码
elif [ 条件判断式 ] 
then
	代码
fi #if语句结束

测试

#!/bin/bash
# 输入参数,大于等于60输出及格,反之输出不及格
if [ $1 -ge 60 ]
then
    echo 及格
elif [ $1 -lt 60 ]
then
    echo 不及格
fi

[root@yellowstarEdu01 shcode]# ./grade.sh  50
不及格
[root@yellowstarEdu01 shcode]# ./grade.sh  80
及格

case语句

类似于Java中的switch…case…

基本语法

case $变量名 in
"值1" )
满足值1执行代码
;;
"值2" )
满足值2执行代码
;;
* )
都不满足,执行代码
;;
esac

测试

#!/bin/bash
# 当命令行参数为1时,输出周一,2时,输出周二,其他情况输出其他
case $1 in
"1" )
    echo 周一
;;
"2" )
    echo 周二
;;
* )
    echo 其他
;;
esac

[root@yellowstarEdu01 shcode]# ./casedemo.sh 1
周一
[root@yellowstarEdu01 shcode]# ./casedemo.sh 3
其他
[root@yellowstarEdu01 shcode]# ./casedemo.sh 2
周二

for循环

基本语法1

for 变量 in 值1 值2 值3...
do 
程序
done

测试

#!/bin/bash
# 打印命令行输入的参数,这里可以看出$*和$@的区别
for i in "$*"
do
    echo 参数为:$i
done

echo ===========================

for i in "$@"
do
    echo 参数为:$i
done

# 输出,从这里我们可以看出$*是把所有参数看成一个整体
[root@yellowstarEdu01 shcode]# ./testfor1.sh 100 200 300
参数为:100 200 300
===========================
参数为:100
参数为:200
参数为:300

基础语法2

for(( 初始值;循环控制条件;变量变化 )) #支持++,--写法
do 
程序
done

测试

#!/bin/bash
# 输出从1加到100的值
SUM=0
for (( i=0;i<=100;i++ ))
do
    SUM=$[$SUM+$i]
done
echo 结果为:$SUM

[root@yellowstarEdu01 shcode]# ./testfor2.sh 
结果为:5050

while循环

基本语法

while [ 条件判断式 ]
do
程序
done

测试

#!/bin/bash
i=0
SUM=0
while [ $i -le $1 ]
do
    SUM=$[$SUM+$i]
    i=$[$i+1]
done
echo 结果为:$SUM

#输出
[root@yellowstarEdu01 shcode]# ./testWhile.sh 10
结果为:55
[root@yellowstarEdu01 shcode]# ./testWhile.sh 100
结果为:5050

read读取控制台输入

基本语法

read (选项)(参数)
-p:读取值时的提示符
-t:指定读取时等待的时间(),如果没有在指定时间内输入,就不再等待

测试

#!/bin/bash
# 读取控制台输入的一个num1值
read -p "请输入一个数NUM1:" NUM1
echo 控制台输入的值为:$NUM1
# 读取控制台输入的一个num2值,在5秒内输入
read -t 5 -p "请输入一个数NUM2:" NUM2
echo 控制台输入的值为:$NUM2

# 输出,第二个参数我们不输入,5秒后终止输入
[root@yellowstarEdu01 shcode]# ./testread.sh
请输入一个数NUM1:10
控制台输入的值为:10
请输入一个数NUM2:控制台输入的值为:

函数

shell编程和其他编程语言一样,有系统函数,也有自定义函数,我们简单介绍两个系统函数

basename

返回完整路径最后/的部分,通常用来获取文件名

basename [pathname] [suffix]

加上suffix会去除文件类型

[root@yellowstarEdu01 shcode]# basename /home/aaa/test.txt
test.txt
[root@yellowstarEdu01 shcode]# basename /home/aaa/test.txt .txt
test

dirname

返回完整路径最后/的前面的部分,用于返回文件路径

dirname [pathname]

[root@yellowstarEdu01 shcode]# dirname /home/aaa/test.txt
/home/aaa

自定义函数

#!/bin/bash
# 写一个函数,计算两数之和
function getSum()
{
    SUM=$[$n1+$n2]
    echo 两数之和为:$SUM
}

# 从控制台获取两个值
read -p "请输入第一个数:" n1
read -p "请输入第二个数:" n2

# 使用函数
getSum $n1 $n2

# 输出
[root@yellowstarEdu01 shcode]# ./myfun.sh 
请输入第一个数:10
请输入第二个数:30
两数之和为:40

定时备份数据库

Shell编程的语法咱也学了那么多了,现在是时候做个小demo巩固一下所学的知识了。

之前也就说了,作为一个Java开发工程师,有时候自己做做小网站发布到服务器,需要做一些数据库的备份,那我们就来做一个定时备份数据库的shell脚本

开发要求

  • 每天凌晨2:30备份数据库myorder到/data/backup/db
  • 备份开始和备份结束能给给出相应的提示
  • 备份后的文件要求以备份时间为文件名,并打包成*.tar.gz的形式,如2022-02-09_105710.tar.gz
  • 为了不占用太多的内存空间,在备份的同时检查是否存在10天前备份的文件,如果有则删除它

分析

因为备份数据库需要的权限比较高,我们讲shell脚本放在/usr/sbin目录下,只有管理员可以执行

每日凌晨自动备份

使用任务调度即可解决

备份开始和结束给出相应提示

这个不重要,echo输出即可

备份后的文件要求以备份时间为文件名,并打包成*.tar.gz的形式

这个较为复杂,我们结合以下图片理解

在这里插入图片描述

删除10天以前的备份文件

使用find命令找到10天前的文件删除即可

解决过程

编写shell脚本

#!/bin/bash
#备份目录
BACKUP=/data/backup/db
#当前时间
DATETIME=$(date +%Y-%m-%d_%H%M%S)
echo $DATETIME
#数据库地址
HOST=localhost
#数据库用户名
DB_USER=root
#数据库密码
DB_PWD=123456
#备份的数据库名
DATABASE=myorder

#创建备份目录,如果不存在就创建
[ ! -d "${BACKUP}/${DATETIME}" ] && mkdir -p  "${BACKUP}/${DATETIME}"

#备份数据库
mysqldump -u${DB_USER} -p${DB_PWD} -h${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}

#删除十天以前的备份文件
find ${BACKUP} -mtime +10 -name "*.tar.gz" -exec rm -rf {} \;

#备份完成提示
echo 数据库备份完成$DATETIME

开启任务调度

crontab -r # 编辑,输入以下语句
30 2 * * * /usr/sbin/mysql_db_backup.sh
# 查看任务调度
[root@yellowstarEdu01 sbin]# crontab -l
30 2 * * * /usr/sbin/mysql_db_backup.sh
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值