【LINUX】Shell编程

目录

1.为什么要学习Shell 编程

2. Shell 是什么

 3. Shell 脚本

4. Shell 的变量

4.1. Shell 变量介绍

4.2. shell 自定义变量

5.设置环境变量(全局变量)

6.位置参数变量

7.预定义变量

8.运算符

9.条件判断

10.流程控制

10.1. if 语句

10.2. case 语句

10.3. for 循环

10.4. while 循环

11. read 读取控制台输入

12.函数

12.1.函数介绍

12.2.系统函数

12.3.自定义函数

13. Shell 编程综合案例

1.为什么要学习Shell 编程

(1)Linux 运维工程师在进行服务器集群管理时,需要编写 Shell 程序来进行服务器管理。
(2)对于 JavaEE 和 Python 程序员来说,工作的需要,你的老大会要求你编写一些 Shell 脚本进          行程序或者是服务器的维护,比如编写一个定时备份数据库的脚本。
(3)对于大数据程序员来说,需要编写 Shell 程序来管理集群。

2. Shell 是什么

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

在计算机科学中,Shell俗称壳(用来区别于核)
是指“为使用者提供操作界面”的软件(command interpreter,命令解析器)。
它类似于DOS下的COMMAND.COM和后来的cmd.exe。
它接收用户命令,然后调用相应的应用程序。

中文名    壳
外文名    shell
性质        命令解析器
用途        接收用户命令

Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。是用户使用 Linux 的桥梁.

用户写了一个指令,该指令不能直接发给Linux内核去执行,而是由shell帮我们去执行,执行完之后再通过shell返回给我们结果。
在Linux中不止一种shell,我们常用的是bash。
可以直接发一个指令给shell,也可以将指令写在一个文件/脚本(.sh shell脚本)里。
shell编程就是在shell脚本中写指令。
在这里插入图片描述

 3. Shell 脚本

1.脚本格式要求:
	脚本以 #!/bin/bash 开头 --->确定shell的类型
    脚本需要有可执行权限
    shell脚本文件以.sh结尾,也可以不以.sh结尾

2.编写第一个Shell 脚本
需求说明:创建一个 Shell 脚本,输出 hello world! 
创建一个目录:mkdir /root/shcode
cd /root/shcode
vim hello.sh
写入:
	#!/bin/bash
	echo "hello,world!"

3.shell脚本的常用执行方式
方式 1:
	首先要给shell脚本加x执行权限:chomod u+x hello.sh
	再输入该脚本的相对路径或绝对路径来执行该脚本
    比如:
	 	使用相对路径:	./hello.sh 
	 	使用绝对路径:	/root/shcode/hello.sh

方式 2:
	不用赋予脚本+x 权限,直接执行即可。(使用以下指令,即使没有执行权限也可以执行)
	使用指令: sh  shell脚本/shell脚本的绝对路径
	比如	sh hello.sh 

4. Shell 的变量

4.1. Shell 变量介绍

(1)	Linux Shell 中的变量分为:系统变量和用户自定义变量。
系统变量:系统自带的变量

(2)	系统变量比如:$HOME、$PWD、$SHELL、$USER 等等
echo $HOME	--->显示当前用户的家目录

(3)	可以通过 set 指令显示出shell中的所有系统变量

4.2. shell 自定义变量

基本语法:
(1)	定义变量:变量名=值  --->不加空格
(2)	撤销变量:unset 变量名
(3)	声明静态变量:readonly 变量 (改变量不能 unset撤销)


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

cd /root/shcode
vim vr.sh
输入: 
	#!/bin/bash
	
	#案例 1:定义变量 A=100  (#为注释符)
	A=100
	#输出变量需要加上$ ($--->引用变量)
	echo $A
	
	#上述输出结果是100,想要输出结果为A=100,这样写(A=以普通文本形式输出,$A引用变量的值)
	echo A=$A 或者 echo "A=$A" 
		
		
	#案例 2:撤销变量 A 
	unset A
	echo "A=$A"    (--->输出 A= )

	
	#案例 3:声明静态的变量 B=2,不能 unset 
	readonly B=2
	echo "B=$B" 
	
保存:wq
最后输入执行命令:sh vr.sh

--------------------------------------------------------------------


shell 变量名的定义规则:
(1)	变量名称可以由字母、数字和下划线组成,但是不能以数字开头。5A=200(×)
(2)	等号两侧不能有空格
(3)	变量名称一般习惯为大写,这是一个规范,我们遵守即可

--------------------------------------------------------------------
将命令的返回值赋给变量:
(1)	A=`date`反引号,运行里面的命令,并把结果返回给变量 A 
(2)	A=$(date) 等价于反引号

案例:
#将指令返回的结果赋给变量
	C=`date` 
	D=$(date)
	echo "C=$C" 
	echo "D=$D"
	
	#使用环境变量 TOMCAT_HOME
	echo "tomcat_home=$TOMCAT_HOME"

5.设置环境变量(全局变量)

可以将变量提升为全局环境变量,供多个shell程序共同使用。

基本语法:
(1)	export 	变量名=变量值 	
(功能描述:将 shell 变量输出为环境变量/全局变量)

(2)	source 	配置文件		    
(功能描述:在某文件中定义环境变量之后,要对该文件进行刷新才能使其生效,即让修改后的配置信息立即生效)

(3)	echo 	$变量名			
(功能描述:查询环境变量的值)


快速入门:
(1)	在/etc/profile 文件中定义 TOMCAT_HOME 环境变量
TOMCAT_HOME --->意思是tomcat的家目录是什么
(2)	查看环境变量 TOMCAT_HOME 的值
vim /etc/profile
	写入:export TOMCAT_HOME=/opt/tomcat
	保存退出
source /etc/profile
echo $TOMCAT_HOME ---输出 /opt/tomcat


(3)	在另外一个 shell 程序中使用 TOMCAT_HOME
在另一个shell程序中写入:
	echo "tomcat_home=$TOMCAT_HOME"


注意:在输出 TOMCAT_HOME 环境变量前,需要让其生效source /etc/profile


shell 脚本的
	单行注释:#
	多行注释:   :<<!   独占一行	
				内容 
			    ! 	   独占一行

6.位置参数变量

1.介绍
当我们执行一个 shell 脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量
比如: ./myshell.sh 100 200 这个就是一个执行 shell 的命令行,可以在 myshell 脚本中获取到参数信息

./myshell.sh --->执行myshell脚本命令
100 200 都是该命令行的参数
使用位置参数变量可以在myshell脚本中获得参数


2.基本语法
$n (功能描述:n 为数字,$0 代表命令本身(如./myshell.sh),$1-$9 代表第一到第九个参数(如:$1 就是100 $2 就是200),十以上的参数需要用大括号包含,如${10})
$* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
$@ (功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)
$# (功能描述:这个变量代表命令行中所有参数的个数)

案例:编写一个 shell 脚本 myshell.sh ,在脚本中获取到命令行的各个参数信息。
vim myshell.sh
	写入:
		#!/bin/bash
		echo "命令本身=$0 第一个参数=$1 第二个参数=$2"
		echo "所有的参数=$*"
		echo "$@"
		echo "参数个数=$#"
		保存退出
sh myshell.sh 100 200

7.预定义变量

1.基本介绍:
预定义变量是 shell 设计者事先已经定义好的变量,可以直接在 shell 脚本中使用


2.基本语法:
(1)	$$ (功能描述:当前进程的进程号(PID))
(2)	$! (功能描述:后台运行的最后一个进程的进程号(PID))
(3)	$?(功能描述:最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一个命令正确执行;如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。)

3.应用实例:
在一个 shell 脚本中简单使用一下预定义变量

vim preVar.sh
	写入:
	#!/bin/bash
	echo "当前执行的进程 id=$$"
	
	#以后台的方式运行一个脚本(在脚本后加一个$),并获取他的进程号
	/root/shcode/myshell.sh &
	
	echo "最后一个后台方式运行的进程 id=$!" 

	echo "执行的结果是=$?"
	保存并退出
sh preVar.sh

8.运算符

1.基本介绍:
学习如何在 shell 中进行各种运算操作。


2.基本语法:
(1)	三种写法:
	$((运算式))
	$[运算式]
	expr m + n 	(expression 表达式)
	 
(2)	注意 expr 运算符间要有空格
	如果希望将 expr 的结果赋给某个变量,使用 `` 或者 $( )

(3)	expr m - n

(4)	expr \*, /, %	乘,除,取余


3.应用实例 oper.sh
案例 1:计算(2+3)X4 的值
案例 2:请求出命令行的两个参数[整数]的和 20 50

vim oper.sh
	写入:
	#!/bin/bash
	#案例 1:计算(2+3)X4 的值
	#使用第一种方式
	RES1=$(((2+3)*4))        --->用一个变量RES1接收
	echo "res1=$RES1"
	保存并退出
sh oper.sh

vim oper.sh
	写入:
	#!/bin/bash
	#使用第二种方式, 推荐使用
	RES2=$[(2+3)*4]
	echo "res2=$RES2"
	保存并退出
sh oper.sh	

vim oper.sh
	写入:
	#!/bin/bash	
	#使用第三种方式 expr 
	TEMP=`expr 2 + 3`       
	RES4=`expr $TEMP \* 4` 
	echo "temp=$TEMP"
	echo "res4=$RES4"
	保存并退出
sh oper.sh

vim oper.sh
	写入:
	#!/bin/bash	
	#案例 2:请求出命令行的两个参数[整数]的和 20 50 
	SUM=$[$1+$2]
	echo "sum=$SUM"
	保存并退出
sh oper.sh 20 50

9.条件判断

1.基本语法:
[ condition ] (注意 condition 前后要有空格)
#非空返回 true,可使用$?验证(0 为 true,>1 为 false)


2.应用实例:
[ hspEdu ]		返回 true 
[ ]				返回 false
[ condition ] && echo OK || echo notok	条件满足,执行后面的语句


3.判断语句:
	常用判断条件:
	(1) = 字符串比较
	(2)	两个整数的比较
		-lt 小于     less than
		-le 小于等于  less equal
		-eq 等于      equal
		-gt 大于      greater
		-ge 大于等于   greater equal
		-ne 不等于     not equal
	(3)	按照文件权限进行判断
		-r 有读的权限
		-w 有写的权限
		-x 有执行的权限
	(4)	按照文件类型进行判断
		-f 文件存在并且是一个常规的文件
		-e 文件存在
		-d 文件存在并是一个目录


4.应用实例:
案例 1:"ok"是否等于"ok"
判断语句:使用 =
案例 2:23 是否大于等于 22
判断语句:使用 -ge
案例 3:/root/shcode/aaa.txt 目录中的文件是否存在
判断语句: 使用 -f

代码如下:
vim ifdemo.sh
	#!/bin/bash
	#案例 1:"ok"是否等于"ok"
	if [ "ok" = "ok"  ]
	then
	        echo "equal"
	fi                    -----> if语句 以if开头 以fi结尾
	
	#案例 2:23 是否大于等于 22
	#判断语句:使用 -ge
	if [ 23 -ge 22 ]
	then
	        echo "大于"
	fi
	
	#案例 3:/root/shcode/aaa.txt 目录中的文件是否存在
	#判断语句: 使用 -f
	if [ -f  /root/shcode/aaa.txt ]
	then
	        echo "文件存在"
	fi
	
	#看几个案例
	if [ ]
	then
	        echo "存在"
	fi
	
	if [ hspEdu01 ]
	then
	        echo "hello hspEdu01"
	fi
sh ifdemo.sh

输出结果:
	equal
	大于
	hello hspEdu01

10.流程控制

10.1. if 语句

1.基本语法:
if [ 条件判断式 ] 
then
	代码
fi

或者 多分支

if [ 条件判断式 ] 
then
	代码
elif [条件判断式] 
then
	代码
fi

2.注意事项:[ 条件判断式 ],中括号和条件判断式之间必须有空格

3.应用实例 ifCase.sh
案例:请编写一个 shell 程序,如果输入的参数,大于等于 60,则输出 "及格了",如果小于 60,则输出 "不及格"
	if [ $1 -ge 60 ]
	then
	        echo "及格了"
	else
	        echo "不及格"
	fi

	或者

	if [ $1 -ge 60 ]
	then
	        echo "及格了"
	elif[ $1 -lt 60]
	then
	        echo "不及格"
	fi

10.2. case 语句

1.基本语法:

case $变量名 in
"值 1")
如果变量的值等于值 1,则执行程序 1
;;
"值 2")
如果变量的值等于值 2,则执行程序 2
;;
…省略其他分支…

*)
如果变量的值都不是以上的值,则执行此程序
;;
esac

应用实例 testCase.sh
案例1:当命令行参数是1时,输出 "周一", 是2时,就输出"周二",其它情况输出"other"
vim testCase.sh
	写入:
	#!/bin/bash
	#案例1:当命令行参数是1时,输出 "周一", 是2时,就输出"周二",其它情况输出"other"
	case $1 in
	"1")
	echo "周一"
	;;
	"2")
	echo "周二"
	;;
	*)
	echo "other..."
	;;
	esac
	保存并退出
	
sh testCase.sh 1
周一

10.3. for 循环

基本语法:

第一种方式:

for 变量 in  值 1  值 2  值 3… 
do
程序/代码
done

应用实例 testFor1.sh
案例:打印命令行输入的参数 [这里可以看出$*  和 $@ 的区别]
	#!/bin/bash
	#案例:打印命令行输入的参数 [这里可以看出$*  和 $@ 的区别]
	#注意:$* 是把输入的参数当作一个整体,所以只会输出一句话
	for i in "$*"
	do
	        echo "num is $*"
	done
	
	#使用 $@ 来获取输入的参数,注意:也是把输入的参数看作一个整体,但这是分别对待;所以有几个参数就输出几句
	echo "======================================"
	for j in "$@"
	do
	        echo "num is $@"
	done

sh testFor1.sh 100 200 300
num is 100 200 300
======================================
num is 100 200 300
num is 100 200 300
num is 100 200 300





第二种方式:

for (( 初始值;循环控制条件;变量变化 ))
do
程序/代码
done

应用实例 testFor2.sh
案例:从 1 加到 100 的值输出显示
	#!/bin/bash
	#案例:从 1 加到 100 的值输出显示
	#定义一个变量SUM
	SUM=0
	for(( i=1; i<=100; i++  ))
	do
	        SUM=$[$SUM+$i]
	done
	echo "总和SUM=$SUM"

sh testFor2.sh 
总和SUM=5050

如果1加到x x由自己输入
	SUM=0
	for(( i=1; i<=$1; i++  ))
	do
	        SUM=$[$SUM+$i]
	done
	echo "总和SUM=$SUM"

sh textFor2.sh 1000
总和SUM=500500

10.4. while 循环

基本语法:
while [ 条件判断式 ]
do
程序/代码
done

注意:while 和 [有空格,条件判断式和[  ]也有空格

应用实例:testWhile.sh
案例:从命令行输入一个数 n,统计从 1+..+ n  的值是多少?
	#!/bin/bash
	SUM=0
	i=0
	while [ $i -le $1 ] 
	do
	SUM=$[$SUM+$i]
	#i 自增
	i=$[$i+1]
	done
	echo "执行结果=$SUM"

sh testWhile.sh 100
执行结果=5050

11. read 读取控制台输入

1.基本语法:
read(选项)(参数)
选项:
	-p:指定读取值时的提示符;
	-t:指定读取值时等待的时间(秒),如果没有在指定的时间内输入,就不再等待了
参数:
	变量:指定读取值的变量名

2.应用实例 testRead.sh
案例 1:读取控制台输入一个 NUM1 值
案例 2:读取控制台输入一个 NUM2 值,在 10 秒内输入。代码:

	#!/bin/bash
	#案例 1:读取控制台输入一个 NUM1 值
	read -p "请输入一个数 NUM1=" NUM1 
	echo "你输入的 NUM1=$NUM1"
	
	#案例 2:读取控制台输入一个 NUM2 值,在 10 秒内输入。
	read -t 10 -p "请输入一个数 NUM2=" NUM2 
	echo "你输入的 NUM2=$NUM2"

sh testRead.sh
请输入一个数 NUM1=100
你输入的 NUM1=100

12.函数

12.1.函数介绍

shell 编程和其它编程语言一样,有系统函数,也可以自定义函数。系统函数中,我们这里就介绍两个。


12.2.系统函数

1.basename 基本语法
功能:返回完整路径最后 / 的部分,常用于获取文件名
basename [pathname] [suffix]
basename [string] [suffix]	

功能描述:basename 命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。
选项:suffix 为后缀,如果 suffix 被指定了,basename 会将 pathname 或 string 中的 suffix 去掉。

案例 1:请返回 /home/aaa/test.txt 的 "test.txt" 部分
basename /home/aaa/test.txt
返回test.txt

如果输入:basename /home/aaa/test.txt .txt
返回test


2.dirname 基本语法
功能:返回完整路径最后 / 的前面的部分,常用于返回路径部分
dirname 文件绝对路径 

功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)

案例 1:请返回 /home/aaa/test.txt 的 /home/aaa 
dirname /home/aaa/test.txt
返回/home/aaa

12.3.自定义函数

基本语法:
[ function ] funname[()]
{
	Action; 
	[return int;]
}

调用直接写函数名:funname	[值]


案例 1:计算输入两个参数的和(动态的获取) testFun.sh
	#!/bin/bash
	#案例 1:计算输入两个参数的和(动态的获取)
	
	#定义函数 getSum 
	function getSum() {
		SUM=$[$n1+$n2] 
		echo "和是=$SUM"
	}

	#输入两个值
	read -p "请输入一个数 n1=" n1 
	read -p "请输入一个数 n2=" n2
	
	#调用自定义函数
	getSum $n1 $n2


sh testFun.sh 
请输入一个数 n1=10
请输入一个数 n2=90
和是=100

13. Shell 编程综合案例

1.需求分析:
(1)	每天凌晨 2:30 备份 数据库 hspedu 到 /data/backup/db
(2)	备份开始和备份结束能够给出相应的提示信息
(3)	备份后的文件要求以备份时间为文件名,并打包成 .tar.gz 的形式,比如:2021-03-12_230201.tar.gz
(4)	在备份的同时,检查是否有 10 天前备份的数据库文件,如果有就将其删除。
(5)	画一个思路分析图

在这里插入图片描述

2.代码 
切换到/usr/sbin/目录下(该目录为root用户执行权限,使用root执行)
vim mysql_db.backup.sh
写入:
	#备份目录
	BACKUP=/data/backup/db
	
	#当前时间
	DATETIME=$(date +%Y-%m-%d_%H%M%S)
	echo $DATETIME
	
	#数据库的地址
	HOST=localhost
	
	#数据库用户名
	DB_USER=root
	
	#数据库密码
	DB_PW=hspedu100
	
	#备份的数据库名
	DATABASE=hspedu

	#创建备份目录, 如果不存在,就创建(这个应该可以用if语句写)
	[ ! -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}
	tar -zcvf $DATETIME.tar.gz ${DATETIME}
	
	#删除对应的备份目录
	rm -rf ${BACKUP}/${DATETIME}

	#删除 10 天前的备份文件
	#查找BACKUP目录下10天前的备份文件 备份文件名字为 *.tar.gz 如果有删除
	find ${BACKUP} -atime +10 -name "*.tar.gz" -exec rm -rf {} \;
	echo "备份数据库${DATABASE} 成功~"

	保存并退出
	
sh /user/sbin/mysql_db.backup.sh

{} --->应该可以不用写

定时:
	crontab -e
	30 2 * * * /user/sbin/mysql_db.backup.sh
	保存并退出

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ja kar ta

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值