【RT-Thread学习笔记】bash shell -e参数

1 前言 1.1 项目背景 这段时间博主在写一些编译构建的脚本,考虑到知识的储备性,之前对bash shell解除最多,而且我们的编译环境是在linux下进行,所以我优选了bash shell脚本。
1.2 功能描述 期间我写了一个脚本,大致的功能就是获取当前操作系统是macos还是linux,如果是linux的话,还需要知道是linux32还是linux64。
2 场景分析 2.1 脚本实现 我们都知道linux系统下有个uname命令可以输出当前系统的详细信息,而macos上由于它是unix系统演变来的,所以它也是支持这个命令的。 经过一番研究,我就决定使用uname-a来获取输出信息,然后从输出信息里面检索关键字,进而判断是什么系统。 脚本实现代码如下:
#! /bin/bash -e   function get_os() {     echo begin to get os ...        os=`uname -a | grep darwin`     if [ $os != ]; then         host_os_name=osx     else         os=`uname -a | grep x86_64`         if [ $os != ]; then             host_os_name=linux64         else             host_os_name=linux32         fi     fi       echo get os name: $host_os_name }   function do_other_things() {         echo do other things ... }   get_os   do_other_things   exit 0 2.2 问题复现 从功能逻辑上分析,没有任何问题,结果我在linux-x64上面一跑,出乎意料了:
bash_shell_e$ ./test_shell_e.sh  begin to get os ... 感觉脚本压根就没跑完啊?怎么回事?
2.3 问题分析 调试代码,先从逻辑上分析没有问题,再使用万能的print大法,不过再bash shell里面就要用echo了。 通过一行行echo添加log,最终定位到是:
os=`uname -a | grep darwin` 执行完这句之后,后面的if语句就没跑进去! 但是uname-a|grepdarwin在我的机器上是可以执行的,并不会报错:
bash_shell_e$ uname -a | grep darwin bash_shell_e$  虽然是啥也没输出。 我们都知道在bash shell里面是通过echo $?来判断上一条命令执行是否成功的:
bash_shell_e$ echo $? 1 bash_shell_e$  bash_shell_e$ ls test_shell_e.sh bash_shell_e$  bash_shell_e$ echo $? 0 嗯哼?返回1,这个引起了我的注意,证明这条命令执行的返回是失败的。 回头再看看脚本的开始,我习惯上是写
#! /bin/bash -e 至于为啥带上-e,以前压根就没去考虑过,反正看到linux下的好多系统脚本就是这样写的,咱这样是像标准看齐,没想到还搞出问题了。
2.4 -e究竟是什么含义? 通过查了一些资料,发现这个-e不简单,它可以对每一条执行的shell脚本,自动判断其是否执行成功,如果执行失败,就立即退出整个脚本的执行。 用代码来体现就是,如果不加-e,你需要对一个命令的执行结果判断,就应该这样:
excute_shell_cmd if [ $? != 0 ]; then     exit 1 fi 而有了-e,就只有这样:
excute_shell_cmd 看,是不是大大简洁了脚本,而不会出现满屏的if-fi。 但是这个带来的最大问题就是,你可能不知道哪条语句就退出了,应该这里退出脚本执行的时候,没有任何输出提示,就好像我的案例场景一样。
2.4 解决办法1 既然知道是-e选项引起的,我去掉试试看:
#! /bin/bash    function get_os() {     echo begin to get os ...        os=`uname -a | grep darwin`     if [ $os != ]; then         host_os_name=osx     else         os=`uname -a | grep x86_64`         if [ $os != ]; then             host_os_name=linux64         else             host_os_name=linux32         fi     fi       echo get os name: $host_os_name }   function do_other_things() {         echo do other things ... }   get_os   do_other_things   exit 0 执行一下:
bash_shell_e$ ./test_shell.sh  begin to get os ... get os name: linux64 do other things ... 得到了正确的结果,在其他平台上,也得到了正确的结果。
2.5 解决办法2 但是,如果我不想去掉-e呢,有没有什么办法? 经过一番调试,我发现这样是可以的:
#! /bin/bash -e   function get_os() {     echo begin to get os ...       osx_name=darwin     linux64_name=x86_64     if [ `uname -a | grep $osx_name` != ]; then         host_os_name=osx     elif [ `uname -a | grep $linux64_name` != ]; then         host_os_name=linux64     else         host_os_name=linux32             fi       echo get os name: $host_os_name }   function do_other_things() {     echo do other things ... }   get_os   do_other_things   exit 0 输出结果如下:
bash_shell_e$ ./test_shell_ok.sh  begin to get os ... get os name: linux64 do other things ... 这里的区别在于,直接把uname-a|grepdarwin的执行结果参与if判断,而不是用一个变量去接收返回;这样居然就通过了。
2.6 扩展延伸 有没有更好的方法调试shell脚本呢?而不是满屏的echo? 这个,下次我再发文介绍些高阶手段吧,敬请期待。
3 更多分享 架构师李肯
一个专注于嵌入式iot领域的架构师。有着近10年的嵌入式一线开发经验,深耕iot领域多年,熟知iot领域的业务发展,深度掌握iot领域的相关技术栈,包括但不限于主流rtos内核的实现及其移植、硬件驱动移植开发、网络通讯协议开发、编译构建原理及其实现、底层汇编及编译原理、编译优化及代码重构、主流iot云平台的对接、嵌入式iot系统的架构设计等等。拥有多项iot领域的发明专利,热衷于技术分享,有多年撰写技术博客的经验积累,连续多月获得rt-thread官方技术社区原创技术博文优秀奖,荣获csdn博客专家、csdn物联网领域优质创作者、2021年度csdn&rt-thread技术社区之星、rt-thread官方嵌入式开源社区认证专家、rt-thread 2021年度论坛之星top4、华为云云享专家(嵌入式物联网架构设计师)等荣誉。坚信【知识改变命运,技术改变世界】!
本项目的所有测试代码和编译脚本,均可以在我的github仓库01workstation中找到。
欢迎关注我的github仓库01workstation,日常分享一些开发笔记和项目实战,欢迎指正问题。
同时也非常欢迎关注我的专栏,有问题的话,可以跟我讨论,知无不答,谢谢大家。

全球区块链资产市场总体情况解析
455KHz中频信号发生器原理图
爱奇艺旗下VR公司开启了新一轮裁员
2023智能汽车高峰论坛——软件定义未来汽车发展方向
智能家居系统带你体验不一样的智能新时代
【RT-Thread学习笔记】bash shell -e参数
澜起科技宣布推出DDR5第四子代RCD芯片
芯启源出席BEYOND国际科技创新博览会
电动客车的电磁兼容问题及EMC要求
什么是窄带物联网?窄带物联网和宽带物联网有什么区别?
电动汽车充电系统介绍
斩获大奖 | 赛昉科技精彩亮相RISC-V年度盛会
带你深入了解实时以太网
移动电源为电池开“外挂”
Maxim推出业内首款2串HB LED驱动器
数字经济助推高质量发展,人工智能加速产业转型
小米MIX2真机图曝光,更强更滑更薄更窄更大+2大顶级黑科技
基于Transformer的大型语言模型(LLM)的内部机制
用电路制作圣诞树
硅步机器人专业ROS交流会