shell脚本之如使用return和exit

文章目录

  • shell脚本之如使用return和exit
    • 一、exit和return基础
      • EXIT退出指令举例
      • 在函数中使用return语句退出举例
    • 二、最佳实践
    • 三、子脚本返回非零状态码时导致主控脚本退出中断的问题
      • 问题描述
      • [重要]问题分析
        • 善用exit $?
        • 使用 sh 调子脚本

shell脚本之如使用return和exit

return和exit各有用途,合理使用可以使shell编程更规范可控。

一、exit和return基础

1、return是一个关键字; exit是一个函数。
2、return是编程语言级别,它表示调用堆栈的返回;exit是系统调用级别,它表示了一个进程的结束。
3、return是函数的退出(返回);exit是进程的退出。

  • exit 0
      正常运行程序并退出程序。使用echo $?返回0,也就是说调用环境认为你的程序执行正常。
  • exit 1
      非正常运行导致退出程序,也可以是其他数字,例如exit -1。系统程序对于程序运行错误是有约定含义的,不为 0 就表示程序运行出错。调用环境根据这个返回值,判断你的程序运行是否正常。

return 0用于函数中,表示函数执行成功并返回 0;而exit 0 则表示当前程序执行成功并且直接退出当前执行脚本或程序。

return -1 表示函数执行失败返回错误;exit 1 (或大于 1)表示程序执行失败并退出程序。

总结: exit用于退出整个shell脚本进程。

EXIT退出指令举例

"exit"命令是终止Bash shell脚本的最常见方法之一。它允许脚本在执行过程中的任何时候退出,并且可以使用可选的退出代码来表示脚本终止的原因。

# 检查一个文件是否存在
if [ -f "myfile.txt" ]; thenecho "The file exists"exit 0 # 成功的退出
elseecho "The file does not exist"exit 1 # 异常的退出并附带说明
fi

在这个例子中,脚本使用“-f”测试运算符检查一个名为“myfile.txt”的文件是否存在。如果文件存在,脚本会向控制台打印一条消息,并使用“exit”命令以成功代码0退出。如果文件不存在,脚本会打印不同的消息,并使用错误代码1退出。

“exit”命令还可以用于处理脚本执行过程中的错误或意外情况。例如,假设一个脚本需要访问可能不可用的资源,如网络服务或数据库。在这种情况下,脚本可以使用“exit”命令以错误消息和适当的退出代码优雅地终止。

在函数中使用return语句退出举例

#!/bin/bash# 定义一个函数并返回数字之和
function add_numbers {local num1=$1local num2=$2local sum=$((num1 + num2))return $sum
}# 调用函数并打印结果
read_file "myfile.txt"# 调用函数并打印结果
add_numbers 3 71
result=$?
echo "3 + 71 = $result" 

在这个例子中,脚本定义了一个名为“add_numbers”的函数,它接受两个参数并返回它们的总和。在函数内部,使用“return”命令以总和作为返回值退出。

**“return”命令也可以用于处理函数内部的错误或意外情况。**例如,假设一个函数需要从一个文件中读取数据,但是该文件不存在。在这种情况下,函数可以使用“return”命令以错误代码和错误消息退出。

#!/bin/bash# 定义一个函数读取文件
function read_file {local file=$1if [ ! -f "$file" ]; thenecho "Error: File $file not found"return 1ficat $file
}

如果文件不存在,函数将打印一个错误消息并返回错误代码1,该代码可以由调用脚本或进程用于相应地处理错误。

**在函数内使用“return”命令是一个很好的方式,可以正确退出函数并将其结果传达给脚本的其他部分或调用进程。**通过使用适当的返回值和错误代码,脚本可以处理意外情况,并提高其整体稳健性和可靠性。

二、最佳实践

  • 函数必须使用return退出,不能用exit。
  • 脚本主体逻辑使用return设置退出码,最后用exit退出脚本。
  • 如果需要精确控制退出码,脚本中的各处逻辑都建议用return。
  • 发生不可处理的错误时,可以直接用exit终止脚本。

三、子脚本返回非零状态码时导致主控脚本退出中断的问题

问题描述

主控脚本A,循环调用子脚本B、C,执行B子脚本exit,发现主控脚本A循环中断了,C子脚本没有调用

[重要]问题分析

开始以为:
exit 会导致整个脚本进程结束,主控制脚本循环也会被中断。测试发现子脚本 exit非零,会导致主控脚本也直接退出

其实最后发现,是我主控日志打印,根据子脚本的 $? 结果,非0时自己exit 的,并不是因为子脚本非0 exit,主控就一定退出!!! 是一场乌龙~

结论:子脚本的exit不会直接导致主脚本退出,主程序要自行处理$?并决定下一步操作。

不过可以这里总结出如下2个比较有用的shell实践技巧:

  • 善用exit $?
  • 使用 sh 调子脚本

善用exit $?

使用函数+return 方式返回状态码,最后 exit $? 方式退出脚本

完整示例demo:

start_mongodb(){$MONGODB_BIN_DIR/mongod -f $MONGO_CONFif [ $? -eq 0 ]; thenecho "MongoDB started successfully"return 0elseecho "Failed to start MongoDB"return 1fi
}stop_mongodb(){$MONGODB_BIN_DIR/mongod -f $MONGO_CONF --shutdownif [ $? -eq 0 ]; then  echo "MongoDB stopped successfully"return 0elseecho "Failed to stop MongoDB"return 1  fi
}status(){if [ -f $MONGODB_PIDFILE ]; thenecho "MongoDB is running, PID: $(cat $MONGODB_PIDFILE)"return 0elseecho "MongoDB is stopped"return 1fi
}function control_mongodb(){case $1 instart)start_mongodb  ;;stop)stop_mongodb;;restart)stop_mongodbstart_mongodb;;status)status;;*)echo "Usage: $0 {start|stop|restart|status}"exit 1esacreturn $? 
}# 调用函数
control_mongodb $1exit $?

在Linux shell脚本中,exit $? 表示使用上一个命令的退出状态码来退出当前shell脚本。
$? 是一个特殊变量,它保存了上一个执行的命令或者函数的退出状态码
退出状态码0表示成功执行,非0通常表示失败或错误。
exit $? 的具体作用是:

  • $? 获取上一个命令的退出码
  • exit 使脚本退出
  • 将上一个命令的退出码作为脚本的最终退出码

使用 sh 调子脚本

使用 sh 调子脚本,通常有下面的几种使用场景:

  1. 强制子脚本在一个干净的环境中运行。sh 会启动一个新的shell实例,不会继承当前shell的任何自定义设置、变量等,可以提供一个干净隔离的运行环境。
  2. 为子脚本设置特定的shell。直接调用子脚本时,使用当前shell(通常是bash),但有时需要指定为sh、csh等其他shell。
  3. 在脚本中改变目录时,调用子脚本使用相对路径。sh 重置了工作目录,使相对路径生效。
  4. 当子脚本需要另一个版本的shell时。直接调用继承当前shell,但 sh 可以指定所需的shell。
  5. 在升级系统shell时,保证子脚本向后兼容。直接调用使用新shell可能出错,但 sh 调用可保持原有的shell。
  6. 出于安全考虑,不信任子脚本,使用 sh 加沙箱隔离
  7. 在守护进程中调用脚本,需要一个干净可预测的新shell环境。
  8. 一些老的脚本依赖 sh 调用,直接转换会破坏原有行为。

总之,使用 sh 调用主要是为了精细控制子脚本的执行环境,符合特定的兼容性要求等。但通常需要时,直接调用更简单。

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

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

相关文章

【ES6】—使用 const 声明

一、不属于顶层对象window 使用const关键字 声明的变量,不会挂载到window属性上 const a 5 console.log(a) console.log(window.a) // 5 // undefined二、不允许重复声明 使用const关键字不允许重复声明相同的变量 cosnt a 5 cosnt a 6 // Uncaught SyntaxEr…

Postman如何做接口测试:什么?postman 还可以做压力测试?

我们都知道, postman 是一款很好用的接口测试工具。不过 postman 还可以做简单的压力测试,而且步骤只需要 2 步。 首先,打开 postman, 编写接口的请求参数。 然后,点击右下方的 runner 运行器,把需要测试的接口拖动到…

Linux实用运维脚本分享

Linux实用运维脚本分享🍃 MySQL备份 目录备份 PING查询 磁盘IO检查 性能相关 进程相关 javadump.sh 常用工具安装 常用lib库安装 系统检查脚本 sed进阶 MySQL备份 #!/bin/bashset -eUSER"backup" PASSWORD"backup" # 数据库数据目录…

学习网络编程No.3【socket理论实战】

引言: 北京时间:2023/8/12/15:32,自前天晚上更新完文章,看了一下鹅厂新出的《扫毒3》摆烂至现在,不知道是长大了,还是近年港片就那样,给我的感觉不是很好,也可能是国内市场对港片不…

Vue 项目搭建

环境配置 1. 安装node.js 官网:nodejs(推荐 v10 以上) 官网:npm 是什么? 由于vue的安装与创建依赖node.js(JavaScript的运行环境)里的npm(包管理和分发工具)&#xff…

Python编程基础-函数

函数定义与调用 将完成某一特定功能并经常使用的代码编写成函数,在需要使用时直接调用 def 函数名(函数参数): 函数体 return 表达式或者值 def printHello(): #打印hello字符串print (hello)def printNum(): #输出0--9数字for i in range(0,10):print (i)return…

js的面对对象总结

ECMAScript支持面向对象(OO)编程,但不使用类或者接口。对象可以在代码执行过程中创建和增强,因此具有动态性而非严格定义的实体。在没有类的情况下,可以采用下列模式创建对象。 1.工厂模式,使用简单的函数创建对象,为…

更新arm的linux编译工具链

虑到目前arm的gcc 5.5的工具链对C17语法支持不足,需要升级下工具链。 以下是详细步骤。使用官方提供的工具链 ARM官方的工具链网站: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads bare-metal这个版本就是没有操作系统(裸机环…

具有弱监督学习的精确3D人脸重建:从单幅图像到图像集的Python实现详解

随着深度学习和计算机视觉技术的飞速发展,3D人脸重建技术在多个领域获得了广泛应用,例如虚拟现实、电影特效、生物识别等。但是,由单幅图像实现高精度的3D人脸重建仍然是一个巨大的挑战。在本文中,我们将探讨如何利用弱监督学习进…

“之江数据安全治理论坛”暨《浙江省汽车数据处理活动规定(专家建议稿)》研讨会顺利召开

研讨会主题 8月10日,“之江数据安全治理论坛”暨《浙江省汽车数据处理活动规定(专家建议稿)》研讨会在浙江大学计算机创新技术研究院举办。 本次研讨会的主题聚焦于“智能网联汽车的数据安全与数据合规”,邀请行业主管部门和数据…

图像处理算法大全(基于libyuv或IPP)----NV12转成I420,RGB24,ARGB集合

《周星星教你学ffmpeg》技巧 libyuv源码: static void NV12ToI420(BYTE* pNV12_Y, BYTE* pNV12_UV, BYTE* pYV12, int width, int height) { libyuv::NV12ToI420(pNV12_Y, width, pNV12_UV, width, pYV12, width, pYV12 height*width, width / 2, pYV12 hei…

【音视频原理】图像相关概念 ① ( 像素 | 分辨率 | 位深 )

文章目录 一、图像相关概念1、像素2、分辨率3、位深 一、图像相关概念 图像相关概念 : 像素 : 图片基本单位 ;分辨率 : 图像的像素尺寸 ;位深 : 记录每个像素点颜色时使用的位数 ;帧率 : 一秒钟传输图片的帧数 , 单位 fps , Frame Per Second ;码率 : 单位时间内视频的数据流量…

什么文件传输协议才能保障跨国文件传输安全又稳定

在当今的全球化时代,跨国文件传输是一种常见而又重要的需求,无论是个人还是企业,都需要通过网络来分享和交换各种类型和大小的文件。但是,跨国文件传输也面临着许多挑战和风险,如何选择一个合适的文件传输协议&#xf…

机器学习与模式识别3(线性回归与逻辑回归)

一、线性回归与逻辑回归简介 线性回归主要功能是拟合数据,常用平方误差函数。 逻辑回归主要功能是区分数据,找到决策边界,常用交叉熵。 二、线性回归与逻辑回归的实现 1.线性回归 利用回归方程对一个或多个特征值和目标值之间的关系进行建模…

(排序) 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 ——【Leetcode每日一题】

❓剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 难度:简单 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。 示例: 输入:nums [1…

02.案列项目Demo

1.创建项目 1. 创建项目 用pycharm 选择对应的编译器,输入对应的文件名,点击创建项目。删除默认外层生成的template和DIRS 配置项: 2. 创建App 创建appo1的命令: python manage.py startapp app01 如果使用pycharm>tool>…

mongodb.使用自带命令工具导出导入数据

在一次数据更新中,同事把老数据进行了清空操作,但是新的逻辑数据由于某种原因(好像是她的电脑中病毒了),一直无法正常连接数据库进行数据插入,然后下午2点左右要给甲方演示,所以要紧急恢复本地的…

深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)

深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)。 一、简介 单点登录(Single Sign On),简称为 SSO。 它的解释是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 ❝ 所谓一次登录,处处登录。同样一处退出,处处退出。 ❞ 二…

【Android Studio】 win11 安装配置 jdk17 超详细

概述 一个好的安装教程能够帮助开发者完成更便捷、更快速的开发。书山有路勤为径,学海无涯苦作舟。我是秋知叶i、期望每一个阅读了我的文章的开发者都能够有所成长。 一、下载JDK JDK官网 这里下载 JDK17 windows x64 installer 二、安装JDK 双击打开下载的 j…

17-工程化开发 脚手架 Vue CLI

开发Vue的两种方式: 1.核心包传统开发模式: 基于 html/css /js 文件,直接引入核心包,开发 Vue。 2.工程化开发模式: 基于构建工具 (例如: webpack)的环境中开发 Vue。 问题: 1. webpack 配置不简单 2. 雷同的基础配置 3. 缺乏统…