当前位置: 首页 > news >正文

Linux Bash 中 $? 的详细用法

$?: The Heart of Error Handling in Bash Scripting

Bash (Bourne Again SHell) 是使用最广泛的 SHell 脚本语言之一,因为它与 Unix 和 Linux 系统兼容。它提供了许多内置函数和变量,使脚本编写更高效,更不容易出错。其中一个变量是 $?, 它是 Bash 脚本错误处理的一个组成部分。这个特殊变量保存最后一个执行命令的退出状态,这对于根据命令成功或失败控制脚本流至关重要。

1. 理解退出状态

在类 unix 操作系统中,理解退出状态的概念是非常必要的。每当命令或程序完成执行时,它都会向 shell 发送一个退出状态。这个退出状态是一个整数,表示命令是否成功。

按照惯例,退出状态为 0 表示成功,而任何非零值 (1-255) 表示错误。每个非零退出状态可以对应于不同类型的错误,允许脚本根据遇到的特定错误采取各种纠正操作。

2. $? 的作用

$? 变量捕捉到了这种退出状态。每次执行完命令后,可以通过 $? 获取执行的状态。

例如:我们想创建一个目录,我们可以使用 $? 检查目录创建是否成功。

mkdir /path/to/directory
if [ $? -eq 0 ]
thenecho "Directory was created successfully."
elseecho "Failed to create the directory."
fi

3. 高级用法

退出状态也可以直接在条件中使用,而不需要明确引用 $?,shell 允许使用逻辑操作符 && 和 || 将命令链接在一起。&& 操作符仅在前一个命令成功 (退出状态为 0) 时运行下一个命令,而 || 操作符仅在前一个命令失败(退出状态非零) 时运行下一个命令。

下面我们使用这些操作符重写前面的脚本:

mkdir /path/to/directory && echo "Directory was created successfully." || echo "Failed to create the directory."

这行代码与前面的脚本相同,但更简洁。

4. 在函数中使用退出状态

正如命令和程序返回退出状态一样,bash 脚本中的函数也可以返回退出状态,这进一步增加了 $? 的功能。当函数完成时,它可以返回退出状态以指示成功或失败,或者向脚本的其余部分发出特定条件的信号。

下面是一个使用退出状态的函数示例

function check_directory {if [ -d "$1" ]thenreturn 0elsereturn 1fi
}check_directory /path/to/directoryif [ $? -eq 0 ]
thenecho "Directory exists."
elseecho "Directory does not exist."
fi

5. 根据特定的退出状态执行操作

非零退出状态可以提供有关所发生错误类型的详细信息。例如,在某些命令中,退出状态为 1 可能表示小问题,而退出状态为 2 则表示严重错误。通过捕获和处理这些特定的状态,您的脚本可以以不同的方式处理不同的错误情况。

下面是如何使用特定退出状态的简单示例

commandcase $? in
0)echo "Command succeeded."
;;
1)echo "Command failed due to minor problem."
;;
2)echo "Command failed due to severe problem."
;;
*)echo "An unknown error occurred."
;;
esac

6. 注意事项

(1) $? 只保存最后执行的命令的退出状态。如果在检查 $? 之前执行了其他命令,退出状态将被覆盖。

(2) 并非所有命令和程序都遵循“0为成功”和“非0为错误”的约定。有些可能使用不同的状态码,或者没有准确地使用退出状态。经常检查您正在使用的命令的手册页或其他文档,以了解不同的退出状态代表什么

我的开源项目

酷瓜云课堂-开源知识付费解决方案

  • course-tencent-cloud(酷瓜云课堂 - gitee仓库)
  • course-tencent-cloud(酷瓜云课堂 - github仓库)
http://www.xdnf.cn/news/543295.html

相关文章:

  • 【算法】定长滑动窗口5.20
  • 畅游Diffusion数字人(30):情绪化数字人视频生成
  • MVDR源码(可直接运行)
  • HarmonyOS NEXT~鸿蒙系统与mPaaS三方框架集成指南
  • 单端传输通道也会有奇偶模现象喔
  • PIL库的图像增强函数
  • 从ISO17025合规到信创适配 解密质检lims系统实验室的 AI 质检全链路实践
  • 【C++】C++的拷贝构造函数介绍使用
  • 【RK3588嵌入式图形编程】-Cairo-形状与填充
  • C++从入门到实战(十六)String(中)String的常用接口(构造接口,析构接口,迭代器,遍历修改,容量管理与数据访问)
  • 零基础设计模式——创建型模式 - 单例模式
  • .NET 10 - 尝试一下Minimal Api的Validation新特性
  • 开源一个记账软件,支持docker一键部署
  • APPtrace 智能参数系统:重构 App 用户增长与运营逻辑
  • C++中String类
  • 《经济日报》深度聚焦|珈和科技携手万果博览荟共筑智慧农业新示范高地 全链赋能蒲江茶果产业数字化转型升级
  • 榕壹云上门家政系统:基于Spring Boot+MySQL+UniApp的全能解决方案
  • 深度剖析ZooKeeper
  • 基于大模型与人工智能体的机械臂对话式交互系统RobotAgent
  • 阿里云CDN刷新预热--刷新URL
  • 【AI 大模型】盘古大模型简介 ( 创建空间 | 体验模型 | 部署模型 )
  • 【华为OD-B卷-打印文件 100分(python、java、c++、js、c)】
  • 面试算法刷题3(核心+acm)
  • LVS原理详解及LVS负载均衡工作模式
  • Java的线程池相关的几个问题
  • Python 训练营打卡 Day 20-奇异值SVD分解
  • STM32F103_LL库+寄存器学习笔记12.2 - 串口DMA高效收发实战2:进一步提高串口接收的效率
  • Java实现基于bitmap的字符串去重统计
  • 鸿蒙路由参数传递
  • sqlite