shell排错

news/2025/10/12 20:20:11/文章来源:https://www.cnblogs.com/chucz/p/19137173

shell排错

常见语法错误

=当做==

#!/bin/bash
number=1
if [ $number = 1 ]; thenecho "Number is equal to 1."
elseecho "Number is not equal to 1."
fi

echo字符表达式丢失引号

#!/bin/bash
number=1
if [ $number == 1 ]; thenecho "Number is equal to 1.
elseecho "Number is not equal to 1."
fi

丢失或意外的标记

删除 if 命令中测试之后的分号

#!/bin/bash
# trouble: script to demonstrate common errors
number=1
if [ $number = 1 ] thenecho "Number is equal to 1."
elseecho "Number is not equal to 1."
fi

预料不到的展开

有时候这个脚本执行正常,其它时间会失败, 这是因为展开结果造成的。把 number 的数值更改为一个空变量

#!/bin/bash
# trouble: script to demonstrate common errors
number=
if [ $number = 1 ]; thenecho "Number is equal to 1."
elseecho "Number is not equal to 1."
fi

经过展开之后,number 变为空值,结果就是这样:

[  = 1 ]

通过为 test 命令中的第一个参数添加双引号,可以更正这个问题:

[ "$number" = 1 ]

其得到了正确的参数个数。除了代表空字符串之外,引号应该被用于这样的场合,一个要展开 成多单词字符串的数值,及其包含嵌入式空格的文件名。

[ "" = 1 ]

逻辑错误

  1. 不正确的条件表达式。很容易编写一个错误的 if/then/else 语句,并且执行错误的逻辑。
  2. “超出一个值”错误。当编写带有计数器的循环语句的时候,为了计数在恰当的点结束,循环语句可能要求从 0 开始计数,而不是从 1 开始,这有可能会被忽视。
  3. 意外情况。比如说一个包含嵌入式空格的文件名展开成多个命令参数而不是单个的文件名。

防错编程

当编程的时候,验证假设非常重要。

cd $dir_name
rm *

cd $dir_name && rm *

但是仍然有可能未设置变量 dir_name 或其变量值为空,从而导致删除了用户家目录下面的所有文件。

[[ -d $dir_name ]] && cd $dir_name && rm *
if [[ -d $dir_name ]]; thenif cd $dir_name; thenrm *elseecho "cannot cd to '$dir_name'" >&2exit 1fi
elseecho "no such directory: '$dir_name'" >&2exit 1
fi

这里,我们检验了两种情况,一个名字,看看它是否为一个真正存在的目录,另一个是 cd 命令是否执行成功。 如果任一种情况失败,就会发送一个错误说明信息到标准错误,然后脚本终止执行,并用退出状态 1 表明脚本执行失败。

验证输入

一个程序可以接受输入数据,那么这个程序必须能够应对它所接受的任意数据。

[[ $REPLY =~ ^[0-3]$ ]]

这条测试语句非常明确。只有当用户输入是一个位于 0 到 3 范围内(包括 0 和 3)的数字的时候, 这条语句才返回一个 0 退出状态。而其它任何输入概不接受。

测试

在各类软件开发中(包括脚本),测试是一个重要的环节。在开源世界中有一句谚语,“早发布,常发布”,这句谚语就反映出这个事实(测试的重要性)。 通过提早和经常发布,软件能够得到更多曝光去使用和测试。经验表明如果在开发周期的早期发现 bug,那么这些 bug 就越容易定位,而且越能低成本 的修复。

if [[ -d $dir_name ]]; thenif cd $dir_name; thenecho rm * # TESTINGelseecho "cannot cd to '$dir_name'" >&2exit 1fi
elseecho "no such directory: '$dir_name'" >&2exit 1
fi
exit # TESTING

因为在满足出错条件的情况下代码可以打印出有用信息,所以我们没有必要再添加任何额外信息了。 最重要的改动是仅在 rm 命令之前放置了一个 echo 命令, 为的是把 rm 命令及其展开的参数列表打印出来,而不是执行实际的 rm 命令语句。这个改动可以安全的执行代码。 在这段代码的末尾,我们放置了一个 exit 命令来结束测试,从而防止执行脚本其它部分的代码。 这个需求会因脚本的设计不同而变化。

测试案例

可以通过谨慎地选择输入数据或者运行边缘案例和极端案例来完成。 在我们的代码片段中(是非常简单的代码),我们想要知道在下面的三种具体情况下这段代码是怎样执行的:

  1. dir_name 包含一个已经存在的目录的名字
  2. dir_name 包含一个不存在的目录的名字
  3. dir_name 为空

通过执行以上每一个测试条件,就达到了一个良好的测试覆盖率。

调试

找到问题区域

if [[ -d $dir_name ]]; thenif cd $dir_name; thenrm *elseecho "cannot cd to '$dir_name'" >&2exit 1fi
# else
# echo "no such directory: '$dir_name'" >&2
# exit 1
fi

通过给脚本中的一个逻辑区块内的每条语句的开头添加一个注释符号,我们就阻止了这部分代码的执行。然后可以再次执行测试, 来看看清除的代码是否影响了错误的行为。

追踪

追踪(tracing)的技术。

一种追踪方法涉及到在脚本中添加可以显示程序执行位置的提示性信息。

echo "preparing to delete files" >&2
if [[ -d $dir_name ]]; thenif cd $dir_name; then
echo "deleting files" >&2rm *elseecho "cannot cd to '$dir_name'" >&2exit 1fi
elseecho "no such directory: '$dir_name'" >&2exit 1
fi
echo "file deletion complete" >&2

bash 还提供了一种名为追踪的方法,这种方法可通过 -x 选项和 set 命令加上 -x 选项两种途径实现。

#!/bin/bash -x
number=1
if [ $number = 1 ]; thenecho "Number is equal to 1."
elseecho "Number is not equal to 1."
fi
$ trouble
+ number=1
+ '[' 1 = 1 ']'
+ echo 'Number is equal to 1.'
Number is equal to 1.

追踪生效后,我们看到脚本命令展开后才执行。行首的加号表明追踪的迹象,使其与常规输出结果区分开来。 加号是追踪输出的默认字符。它包含在 PS4(提示符4)shell 变量中。可以调整这个变量值让提示信息更有意义。 这里,我们修改该变量的内容,让其包含脚本中追踪执行到的当前行的行号。注意这里必须使用单引号是为了防止变量展开,直到提示符真正使用的时候,就不需要了。

$ export PS4='$LINENO + '
$ trouble
5 + number=1
7 + '[' 1 = 1 ']'
8 + echo 'Number is equal to 1.'
Number is equal to 1.

可以使用 set 命令加上 -x 选项来启动追踪,+x 选项关闭追踪。这种技术可以用来检查一个有错误的脚本的多个部分。

#!/bin/bash
number=1
set -x # Turn on tracing
if [ $number = 1 ]; thenecho "Number is equal to 1."
elseecho "Number is not equal to 1."
fi
set +x # Turn off tracing

执行时检查数值

伴随着追踪,在脚本执行的时候显示变量的内容,以此知道脚本内部的工作状态,往往是很用的。

#!/bin/bash
number=1
echo "number=$number" # DEBUG
set -x # Turn on tracing
if [ $number = 1 ]; thenecho "Number is equal to 1."
elseecho "Number is not equal to 1."
fi
set +x # Turn off tracing

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

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

相关文章

原木

短线大概率有个C5

格式化输出与文本处理

格式化输出与文本处理以下和vim都是程序,但是以下所讲述的都是命令行工具,vim是一个编辑器,是有本质区别的文本应用程序 到目前为止,我们已经知道了一对文本编辑器(nano 和 vim),看过一堆配置文件,并且目睹了许…

2025年10月镀锌卷板厂家最新推荐排行榜,有花镀锌卷板,无花镀锌卷板,高锌层镀锌卷板,批发镀锌卷板公司推荐

在工业制造与建筑建材领域,镀锌卷板作为基础防腐材料,其品质直接影响终端产品的使用寿命与安全性能。当前市场上,镀锌卷板厂家数量众多,产品质量参差不齐:部分厂商存在锌层厚度不达标、加工时锌层易脱落等问题,导…

React 19.2 重磅更新!这几个新特性终于来了

大家好,我是 Immerse,一名独立开发者、内容创作者、AGI 实践者。 关注公众号:沉浸式趣谈,获取最新文章(更多内容只在公众号更新) 个人网站:https://yaolifeng.com 也同步更新。 转载请在文章开头注明出处和版权…

Akka.NET高性能分布式Actor框架完全指南

Akka.NET是.NET平台上功能完整的Actor模型实现,提供高性能的分布式计算能力。该项目包含完整的Actor系统、集群管理、持久化、流处理等核心功能,支持构建高并发、高可用的分布式应用程序。Akka.NET - .NET平台的Acto…

基于Docker搭建MySQL Cluster

1.整体介绍 1.1整体结构1.2搭建步骤搭建3个MySQL实例. 将3个MySQL实例组建集群. 搭建MySQL Router.2.搭建MySQL 2.1 MySQL配置文件及数据文件目录结构 /data └── mysql├── 3301 #存放数据目录├── 3302├── …

某中心与华盛顿大学公布机器人研究奖项与学者名单

某中心与华盛顿大学联合公布科学中心第二届学者名单及五项机器人研究奖项,涵盖机器人安全控制、深度强化学习、多机器人系统等前沿技术领域,并宣布加入云基础设施未来研究中心推动下一代云计算创新。某中心与华盛顿大…

会话跟踪方案

Cookie 什么是Cookie?概念:存储在用户浏览器端的一个小型数据文件,用于跟踪和保存用户的状态信息 用处:主要用于保持用户登录状态、跟踪用户行为、存储用户偏好等 存储在浏览器端优点: HTTP协议中支持的技术 缺点:…

阻塞、非阻塞、同步、异步的区别是什么?

同步异步描述的是被调用方。阻塞非阻塞描述的是调用方。二者没有必然联系。阻塞是调用方A发出命令后,必须等待B返回结果。非阻塞是调用方A发出命令后,A不需要等待B,可以做自己的事情。 同步是B收到A的指令之后会立即…

如何防范员工泄露数据给 AI?2025年选型与落地实战版

结论:面向已经开展 AI 办公、又担心把客户隐私与业务机密“喂给”第三方模型的企业,优先选用 AI-FOCUS 团队的「滤海 AI DLP」。通过流式网关把“检测—策略—处置—留痕”前置到数据进入 LLM 之前,统一覆盖文本、文…

Linux文本编辑三剑客之grep

Linux 文本编辑三剑客之 grepLinux 文本处理三剑客是面试和后端工作中较为常见的。需要掌握:grep:文本过滤、筛选 sed:文本编辑加工 awk:文本格式化输出本节内容基于正则表达式: 正则表达式 借助正则表达式可以快…

Linux文本编辑三剑客之sed

Linux 文本编辑三剑客之 sedLinux 文本处理三剑客是面试和后端工作中较为常见的。需要掌握:grep:文本过滤、筛选 sed:文本编辑加工 awk:文本格式化输出本节内容基于正则表达式: 正则表达式 借助正则表达式可以快速…

做了项目经理才发现:上台发言,其实都有套路

在项目推进过程中,总有不少场合需要你上台发言:项目启动会、阶段汇报、庆功宴……这时,你得站在众人面前,清晰表达自己的想法。 有的人发言平淡无奇,内容枯燥,让人听得昏昏欲睡。而有的人一开口,就能吸引大家的…

占位符

a a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\ a\

什么是IO多路复用?

什么是IO多路复用? 多路复用也是面试比较常见的,尤其对于后端,因为很多中间件例如Redis、Nginx、Netty 以及jdk的 NIO 实现都用到了多路复用技术,作为实现高性能的重要底层手段是需要掌握的,下面总--分--总梳理一…

进程、线程和协程之间的区别和联系

进程、线程和协程之间的区别和联系 一、进程 进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以…

挣点小钱的副业(附带新手教程)0元的快乐

老话说得好,钱难挣,那啥难吃。一到发薪日,小花就得给花呗、抖付、美团月付、支付宝、余额宝“翻牌子”,生怕哪个逾期。最怕的就是月月光,还倒欠一屁股债。 双十一即将来临,你不知道的优惠券内部价格,还在傻傻用…

Linux文本编辑三剑客之awk

Linux 文本编辑三剑客之 awkLinux 文本处理三剑客是面试和后端工作中较为常见的。需要掌握:grep:文本过滤、筛选 sed:文本编辑加工 awk:文本格式化输出文章只列举常用的,不会完全把手册复述一遍本节内容基于正则表…

软考~高效的系统规划与管理师考试—知识篇—V2.0—第四章 IT 服务规划设计 — 2017 年 2018 年 2020 年 2022 年 2023 年

软考~高效的系统规划与管理师考试—知识篇—V2.0—第四章 IT 服务规划设计 — 2017 年 & 2018 年 & 2020 年 & 2022 年 & 2023 年pre { white-space: pre !important; word-wrap: normal !important; …

应用安全 --- 安卓安全 之 文件校验

应用安全 --- 安卓安全 之 文件校验文件校验就是在dex或so中使用代码验证文件的唯一性指纹比如md5,sha1 验证方法 修改文件的不重要的比特位打开验证如果app闪退表示存在校验