【Linux】Shell脚本之函数的操作+实战详解(建议收藏⭐)

news2024/11/16 9:22:53

🍁博主简介

  🏅云计算领域优质创作者
  🏅华为云开发者社区专家博主
  🏅阿里云开发者社区专家博主
💊交流社区:运维交流社区 欢迎大家的加入!

文章目录

  • shell脚本函数
    • 设置函数的意义
    • 函数的基本格式
    • 函数的调用+实例
  • 函数的返回值
    • 函数的传参
    • 函数变量的作用范围
  • * 函数的参数
    • *.1 参数的用法
    • *.2 参数的表示方法
    • *.3 参数的案例
      • *3.0 什么是阶乘?
      • *.3.1 求1到6的阶乘
      • *.3.2 求1到6的阶乘,只输出6的阶乘
    • *.4 判断是否为文件
    • *.5 递归函数
      • *.5.1 递归显示var下的log里面有哪些是目录
      • *.5.2 交互式 递归方式计算你输入的数值作为阶乘
  • 如何查看脚本执行过程?
  • 函数重点:
    • 举例重点5:启动脚本模板(可根据自己的jar包名称自行修改)
  • 相关文章:

shell脚本函数

设置函数的意义

函数是一段可以重复利用有组织的代码;可以减少代码,提高代码利用率,使脚本结构更加清晰。

函数的基本格式

function 函数名(){
	执行代码
	[return x]                       #使用return或exit可以显示的结束函数
}
函数名(){							 #函数名后面()是没有内容的
	执行代码							 #我们执行的命令内容放在{}里面
}

这样只是写了函数,但是没有调用,所以执行脚本不会有输出。

函数的调用+实例

  • 实例1

直接写函数名

#!/bin/bash

function f1 {
	echo "函数测试"
}

f1

输出结果为:
函数测试

  • 实例2
#!/bin/bash

function f1 {
	echo "函数测试"
}


f1() {
	echo "这是没有function的函数测试"
}

f1

输出结果为:
这是没有function的函数测试

在这里插入图片描述

  • 实例3
#!/bin/bash

function f1 {
	echo "函数测试"
}


f1() {
	echo "这是没有function的函数测试"
}

f1

f2() {
	echo "这是function的函数测试2"
}

f2

输出结果为:
这是没有function的函数测试
这是function的函数测试2

  • 实例4
#!/bin/bash

function f1 {
	echo "函数测试"
}


f1() {
	echo "这是没有function的函数测试"
}

#f1

f2() {
	echo "这是function的函数测试2"
}

#f2

f3() {
	echo -e "我想输出函数的f1和f2,结果为:\n $(f1) \n $(f2)"
}
f3

输出结果为:
我想输出函数的f1和f2,结果为:
这是没有function的函数测试
这是function的函数测试2

  • 总结:

1.直接写函数中调用

2.函数直接写函数名同名函数后一个生效

3.调用函数一定要先定义

4.只要先定义了调用的其他函数定义顺序无关

函数的返回值

return表示退出函数并返回一个退出值,脚本中可以用 $ ? 变量显示该值

1.函数结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码

2.退出状态码必须是0~255,超出时值将为除以256取余

  • 实例1:通过return返回一个乘积
#!/bin/bash

function test1 {
	read -p "请输入一个数字:" num
	return $[$num*2]
}

test1

echo $?

输出结果为:
请输入一个数字:20
40

为什么会变成40呢?是因为里面写了交互式输入的数字*2,结果在$?返回值里返回。

在这里插入图片描述

  • 实例2
#!/bin/bash


sum() {
	read -p "请输入第一个数:" num1
	read -p "请输入第二个数:" num2
	echo "刚刚输入的两个数分别为:$num1$num2"
	SUM=$[ $num1 + $num2 ]
	echo "两个数的和为:$SUM"
}
sum

结果为:

请输入第一个数:52
请输入第二个数:10
刚刚输入的两个数分别为:52 和 10
两个数的和为:62

在这里插入图片描述

函数的传参

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n的形式来获取参数的值,例如:$1表示第一个参数,$2表示第二个参数…即使用位置参数来实现参数传递。

#!/bin/bash

add () {
	let sum=$1+$2
	echo $sum
}
#add(输出的数是你写的数)
add $1 $2
#函数传参【传的是位置变量】

结果为:24

在这里插入图片描述

函数变量的作用范围

1.函数在shell脚本中仅在当前shell环境中有效

2.Shell脚本中变量默认全局有效

3.将变量限定在函数内部使用local命令

    3.1函数内部变量通过local来实现

    3.2通过定义myfun函数,在其内部设置局部变量i

    3.3函数内部和外部分别赋值,进行结果验证。

ps:

全局变量代表整体可以使用
局部变量代表的是全局变量里面可以使用其中一部分

#!/bin/bash

myfun(){
	local i 
	i=6
	echo $i
}

i=8

myfun
echo $i

local定义的是局部变量;
局部变量是6;全局变量是8;所以输出的结果是6和8
如果吧local这行注释了,那么输出的结果就是6和6;为什么呢?
因为两个全局变量,在脚本中只能执行一个全局变量,且是从上往下,所以输出的只有6。

在这里插入图片描述

* 函数的参数

*.1 参数的用法

函数名称:参数1,参数2,参数3

*.2 参数的表示方法

$1 $2 3......... 3......... 3.........{10}${11}

*.3 参数的案例

*3.0 什么是阶乘?

阶乘(factorial)是基斯顿·卡曼(Christian Kramp, 1760 – 1826)于1808年发明的运算符号。
阶乘,也是数学里的一种术语。

阶乘指从1乘以2乘以3乘以4一直乘到所要求的数。

例如1:所要求的数是4,则阶乘式是1*2*3*4,也可以是4*3*2*1,得到的积是24,24就是4的阶乘。
例如2:所要求的数是6,则阶乘式是1*2*3*……*6,也可以是6*5*4*3*2*1,得到的积是720,720就是6的阶乘。
例如3:所要求的数是n,则阶乘式是1*2*3*……*n,设得到的积是x,x就是n的阶乘。

在表达阶乘时,就使用“!”来表示。如h阶乘,就表示为h!

阶乘一般很难计算,因为积都很大。

以下列出1至10的阶乘。

1!=1,

2!=2,

3!=6,

4!=24,

5!=120,

6!=720,

7!=5040,

8!=40320

9!=362880

10!=3628800

另外,数学家定义,0!=1,所以0!=1!

通常我们所说的阶乘是定义在自然数范围里的,小数没有阶乘,像0.5!,0.65!,0.777!都是错误的。
但是,有时候我们会将Gamma函数定义为非整数的阶乘,因为当x是正整数n的时候,Gamma函数的值是n-1的阶乘。 伽玛函数(Gamma Function)
Γ(x)=∫e^(-t)*t^(x-1)dt (积分下限是零上限是+∞)(x<>0,-1,-2,-3,……)
运用积分的知识,我们可以证明Γ(x)=(x-1) * Γ(x-1)
所以,当x是整数n时,Γ(n) = (n-1)(n-2)……=(n-1)!
这样Gamma 函数实际上就把阶乘的延拓。

*.3.1 求1到6的阶乘

#!/bin/bash

#求阶乘1到6的阶乘
jiecheng (){
	num=1
	for i in {1..6};do
		let num=$i*$num
		echo $num
	done
}

jiecheng

过程为:

1*1
1*2
1*2*3
1*2*3*4
1*2*3*4*5
1*2*3*4*5*6

结果为:

在这里插入图片描述

*.3.2 求1到6的阶乘,只输出6的阶乘

如果想适用于4、5或其他的阶乘,可以吧1…6改为1…指定的最高数就可以算出来了。

#!/bin/bash

cheng (){
	num=1
	for i in {1..6};do
		let num=$i*$num
	done
	echo $num
}
cheng

结果为:

在这里插入图片描述

为什么等于720呢?看上去和*.3.1写的一模一样,其实不一样,仔细看;
一个echo $num在for循环内,一个在for循环外;
在for循环内,会每次循环都输出一次结果,而在for循环外,只会输出循环的最后一次结果,所以,该结果等于720,也就是6的阶乘。

*.4 判断是否为文件

#!/bin/bash
file=/home/abc.txt
wen (){
	if [ -f $file ];then  #判断是否为文件
		return 80
	else
		return 40
	fi
}
wen
echo $?

结果为:

在这里插入图片描述

脚本解析:
如果没有哪个文件也是会返回40的;

在这里插入图片描述

*.5 递归函数

*.5.1 递归显示var下的log里面有哪些是目录

#!/bin/bash
#列出目录文件的列表,目录可用颜色表示(蓝色表示目录;白色表示文件)文件显示层及关系
list (){
        for i in $1/*;do  #$1下面的所有内容
                if [ -d $i ];then   #-d代表是目录 只要是目录的我就用蓝色显示
                        echo -e "\e[34m$i\e[0m"
                        #标准格式【】里面的内容是表示颜色  -e表示转义字符标识
                        echo $i
                        list $i " $2"
                else
                        echo "$2$i"
                fi
        done
}
list $1 $2 #调用变量

执行结果:

在这里插入图片描述

*.5.2 交互式 递归方式计算你输入的数值作为阶乘

#!/bin/bash
#交互式 递归方式计算你输入的数值作为阶乘
#比如我第一次输入5
fun (){
	if [ $1 -eq 1 ];then
   		echo 1
	else
		#5不等于1执行else的 此时tp=5-1=4;res=4 此时echo为5*4
		local tp=$[ $1 - 1 ]  #这个是局部  
  		res=$(fun $tp)  #相当于直接调用tp本身
 	 	echo $[ $1 * $res ] #$1是5
	fi
}
 
read -p "请输入:" num
res=$(fun $num)
echo $res
 
 
#执行过程
#fun 5 $1=5 tp=4 res=fun 4 echo 5 * 4()      5*4*3*2*1
#fun 4 $1=4 tp=3 res=fun 3 echo 4 *3(fun)    4*3*2*1
#fun 3 $1=3 tp=2 res=fun 2 echo 3 * 2(fun)   3*2*1
#fun 2 $1=2 tp=1 res=fun 1 echo 2*1(fun)     2*1
#fun 1 $1  echo 1                            1  

执行结果:

在这里插入图片描述

如果还是看不懂过程,可以使用 sh -x 脚本名称 来看脚本执行过程,或者是在脚本中的#!/bin/bash/下一行加set -x;就可以看到脚本执行的过程了。适合与for循环这一类的工程。

如何查看脚本执行过程?

可以使用 sh -x 脚本名称 来看脚本执行过程,或者是在脚本中的#!/bin/bash/下一行加set -x;就可以看到脚本执行的过程了。适合与for循环这一类的工程。

  • 实例1:sh -x 脚本名称
sh -x 脚本名称

在这里插入图片描述

  • 实例2:在脚本中的#!/bin/bash/下一行加set -x
#!/bin/bash
set -x

脚本:

在这里插入图片描述

执行:

在这里插入图片描述

函数重点:

函数返回值return,当函数中遇到return函数结束。

  • 1.只有函数被调用,函数体内的代码才会被执行;
  • 2.区分脚本和函数的位置变量,函数体内使用函数传递的位置变量;
  • 3.在其他脚本引用函数,需要source或.加脚本名,引用函数;
  • 4.如果return没有指定返回值,则默认返回上一条命令的返回值。
  • 5.函数大多数运用于case循环判断中,来写启动、停止、重启、查看状态等。

举例重点5:启动脚本模板(可根据自己的jar包名称自行修改)

使用方法:sh start.sh start/stop/restart/status

#!/bin/bash

USAGE="Usage: $0 [start|stop|restart|status]"

#jar包进程
jin (){
	ps -ef | grep -v grep | grep cs.jar | wc -l
}

start (){
	if [ $(jin) -ge 1 ];then
		echo "该程序进程存在"
	else
		java -jar cs.jar  > /dev/null &
		if [ $(jin) -ge 1 ];then
			echo "成功启动该程序"
		else
			echo "程序还未启动,请检查程序日志或者是脚本里的启动程序名称是否有误"
		fi
	fi 
}

stop (){
	ps -ef | grep -v grep | grep cs.jar | awk '{ print " kill -9 " $2 }' | sh
	if [ $(jin) -ge 1 ];then
		echo "程序还没有停止,请检查脚本里的程序名称是否有误"
	else
		echo "该程序已停止"
	fi
}

restart (){
	stop
	start
}

status (){
	if [ $(jin) -ge 1 ];then
		echo "有此进程,该服务正在运行中"
	else
		echo "此进程不存在,需要启动服务的时候记得执行脚本哈!"
	fi
}

case $1 in
	start)
		start
	;;
	stop)
		stop
	;;
	restart)
		restart
	;;
	status)
		status
	;;
	*)
	echo -e $USAGE
esac

相关文章:

文章名文章地址
【Linux】 shell脚本的创建及使用 《入门到实践》详解[⭐建议收藏!!⭐]https://liucy.blog.csdn.net/article/details/130111812
【Linux】Shell脚本之函数的操作+实战详解[⭐建议收藏!!⭐]https://liucy.blog.csdn.net/article/details/130387377
【Linux】Shell脚本之 if判断、case判断、for循环、while循环 + 实战详解[⭐建议收藏!!⭐]https://liucy.blog.csdn.net/article/details/130387523

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/504386.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

物联网|蓝牙4.0BLE协议栈简介|IAR集成开发环境简介|IAR各版本下载链接|物联网之蓝牙4.0 BLE基础-学习笔记(2)

文章目录 129-142暂停&#xff0c;待续3、蓝牙4.0BLE协议栈简介4、IAR集成开发环境简介Tips: BLE协议结构图介绍Tips IAR各版本下载链接 129-142暂停&#xff0c;待续 3、蓝牙4.0BLE协议栈简介 问题: 1、什么是LE协议栈?BLE协识栈与BLE协议的关系&#xff1f; 协议&#xff…

数据结构与算法(Java版) | 队列的应用场景和介绍

队列的一个应用场景 给大家介绍完稀疏数组这种数据结构之后&#xff0c;接下来我再来给大家介绍另外一种数据结构&#xff0c;即队列。 队列&#xff0c;听其名而知其义&#xff0c;相信大家应该都在现实生活中见过&#xff0c;比如在火车站排队买票&#xff0c;或者在麦当劳…

轻NAS搭建 - 使用微力同步搭建私人云盘,无需公网IP也能远程访问

文章目录 1.前言2. 微力同步网站搭建2.1 微力同步下载和安装2.2 微力同步网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 私有云盘作为云存储概念的延伸&#xff0c;虽然谈不上多么新颖&#xff0c;但是其…

图神经网络:在Cora数据集上动手实现图神经网络

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook。超链。提取码8888。 文章目录 代码实操1&#xff1a;GCN的复杂实现代码实操2&#xff1a;GCN的简单实现…

IntelliJ Platform-Plugins-获取方法相关信息(PsiElement/PsiMethodImpl)

PsiElement接口是文件中光标所在的那个字段&#xff0c;或者光标所在的那个方法的抽象&#xff0c;例如下图中PsiElement就是public String getName()&#xff0c;它的实现类是PsiMethodImpl 下面的代码会演示&#xff1a;如果光标在方法上&#xff0c;就打印方法名字&#x…

「Cpolar」内网穿透实现在外远程连接MongoDB数据库【端口映射】

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后端的开发语言A…

第二十四章 Unity 纹理贴图

通常情况下&#xff0c;3D网格模型只能展示游戏对象的几何形状&#xff0c;而表面的细节则纹理贴图提供。纹理贴图通过UV坐标“贴附”在模型的表面。当然&#xff0c;这个过程不需要我们在Unity中完成&#xff0c;而是在建模软件中完成的。通常情况下&#xff0c;我们通过3ds m…

鸿蒙Hi3861学习九-Huawei LiteOS-M(互斥锁)

一、简介 互斥锁又被称为互斥型信号量&#xff0c;是一种特殊的二值信号量&#xff0c;用于实现对共享资源的独占式处理。 任意时刻互斥锁的状态只有两种&#xff1a;开锁或闭锁。 当有任务占用公共资源时&#xff0c;互斥锁处于闭锁状态&#xff0c;这个任务获得该互斥锁的使用…

C++系列六:一文打尽C++运算符

C运算符 1. 算术运算符2. 关系运算符3. 逻辑运算符4. 按位运算符5. 取地址运算符6. 取内容运算符7. 成员选择符8. 作用域运算符9. 总结 1. 算术运算符 算术运算符用于执行基本数学运算&#xff0c;例如加减乘除和取模等操作。下表列出了C中支持的算术运算符&#xff1a; 运算…

Oracle 19C 单机环境升级RU(19.3升级至19.12)

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

鸿蒙Hi3861学习五-Huawei LiteOS-M(任务管理)

一、任务简介 关于任务的相关介绍&#xff0c;之前文章有比较详细的介绍&#xff0c;这里不做过多解释&#xff0c;可以参考如下文章&#xff1a;FreeRTOS学习二&#xff08;任务&#xff09;_t_guest的博客-CSDN博客 而LiteOS的主要特性可以总结为如下几点&#xff1a; LiteO…

〖数据挖掘〗weka3.8.6的安装与使用

目录 背景 一、安装 二、使用explorer 1. 介绍 2.打开自带的数据集(Preprocess) 1.打开步骤 2.查看属性和数据编辑 3.classify 4.Cluster 5.Associate 6.Select attributes 7.Visualize 待补充 背景 Weka的全名是怀卡托智能分析环境&#xff08;Waikato Environme…

低代码平台解读—如何不写代码创建表单和维护表单

工作表新建与修改——敲敲云 新建工作表的流程包含 新建工作表/编辑公祖表为工作表添加字段&#xff0c;例如“员工档案”表中有姓名、性别、年龄等字段为字段设置属性工作表布局工作表预览、保存、关闭 1、新建工作表/修改工作表 新建工作表 修改工作表 2、为工作表添加字段 …

c#笔记-定义类

声明类 类可以使用帮助你管理一组相互依赖的数据&#xff0c;来完成某些职责。 类使用class关键字定义&#xff0c;并且必须在所有顶级语句之下。 类的成员只能有声明语句&#xff0c;不能有执行语句。 class Player1 {int Hp;int MaxHp;int Atk;int Def;int Overflow(){if (…

算法记录 | Day55 动态规划

392.判断子序列 思路&#xff1a; 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义: dp[i][j] 表示以下标i-1为结尾的字符串s&#xff0c;和以下标j-1为结尾的字符串t&#xff0c;相同子序列的长度为dp[i][j]。 2.确定递推公式&#xff1a; if (s[i - 1] t[…

线程同步、生产者消费模型和POSIX信号量

gitee仓库&#xff1a; 1.阻塞队列代码&#xff1a;https://gitee.com/WangZihao64/linux/tree/master/BlockQueue 2.环形队列代码&#xff1a;https://gitee.com/WangZihao64/linux/tree/master/ringqueue 条件变量 概念 概念&#xff1a; 利用线程间共享的全局变量进行同…

单片机c51中断 — 开关状态监测

项目文件 文件 关于项目的内容知识点可以见专栏单片机原理及应用 的第五章&#xff0c;中断 图中 P2.0引脚处接有一个发光二极管 D1&#xff0c;P3.2引脚处接有一个按键。要求分别采用一般方式和中断方式编程实现按键压下一次&#xff0c;D1 的发光状态反转一次的功能。 查询…

从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象

目录 1. 构造函数的初始化列表 1.1 初始化列表概念 1.2 初始化列表注意事项 2. 构造函数的explicit关键字 2.1 C语言的隐式类型转换 2.2 explicit 关键字使用 3. static成员 3.1 static的概念 3.2 static成员特性 3.3 static成员使用场景 4. 友元&#xff08;frien…

【Java 基础】类和对象 方法重载详解

《Java 零基础入门到精通》专栏持续更新中。通过本专栏你将学习到 Java 从入门到进阶再到实战的全套完整内容,所有内容均将集中于此专栏。无论是初学者还是有经验的开发人员,都可从本专栏获益。 订阅专栏后添加我微信或者进交流群,进群可找我领取 前端/Java/大数据/Python/低…

Linux 常用命令(1)

文章目录 Linux 常用命令格式 clear 清屏清屏获取当前目录的路径 pwd目录切换命令 cd进入上一级目录进入当前目录的文件夹 ta中(假设这里有一个文件夹ta)进入主目录进入根目录 显示目录内容 ls显示详细信息&#xff0c;包含文件属性显示全部内容&#xff0c;包含隐藏文件&#…