0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux shell脚本经验分享

汽车玩家 来源:面包板社区 作者:面包板社区 2020-04-04 17:28 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

作为一枚Linux嵌入式程序猿,写shell脚本也是经常碰到的工作,在这个过程中或多或少踩过一些坑,也积累了一些经验,在此分享给大家,希望能对大家有点帮助。

1. 指定bash

我们知道在shell 脚本的第一行,都应该指定bash,那#!之后到底应该是什么呢?

这个问题估计不同的人的回答可能都不一样。我见过/usr/bin/env bash,也见过/bin/bash,还有/usr/bin/bash,还有/bin/sh,还有/usr/bin/env sh。我自己也用过其中过的几个,其实在很多情况下,以上几种写法效果都是相同的。但是,坑我们的往往就是少数情况~

如果恰好碰到系统的默认shell不是bash怎么办?比如某Linux发行版的某个版本,默认的 sh 就不是 bash。如果系统的bash不是在/usr/bin/bash怎么办?

还有关于bash和sh的一些小区别:

假设我们写一小段脚本,看看运行结果!

#!/bin/sh

source mlryj.sh

echo “hello world!”

执行结果:

Linux shell脚本经验分享

然后我们将脚本改成这样

#!/bin/bash

source mlryj.sh

echo “hello world!”

执行结果:

Linux shell脚本经验分享

从结果看,在#!/bin/sh的情况下,在mlryj.sh这个脚本不存在的情况下,source不成功,不会运行source后面的代码。

而在#!/bin/bash的情况下,虽然source不成功,但是还是运行了source后面的echo语句。

为什么会这样呢?

接下来我们看一看/bin/sh是个什么东西。

Linux shell脚本经验分享

从上面可以看到,sh只是bash的一个软链接,在一般的linux系统当中,sh调用执行脚本相当于打开了bash的posix模式,也就是说 /bin/sh 相当于 /bin/bash --posix。posix的特定规范之一是,当某行代码出错时,便不继续往下解释。

把脚本改成如下图所示的格式,我们得到运行结果和#!/bin/sh是一样的。

#!/bin/bash --posix

source mlryj.sh

echo “hello world!”

推荐大家使用 /usr/bin/env bash 和 /bin/bash。前者通过env添加一个中间层,让env在PATH中搜索bash;后者毕竟是有官方背书的,约定俗成的bash位置。但是当脚本出现了错误怎么办呢?请看Tip2。

2. set -e 和 set -x

好了,关于指定bash已经完成了。接下来该开始写shell脚本第二行、第三行。

小编建议:在你开始构思并写下具体的代码逻辑之前,先插入一行“set -e”和一行“set -x”。

set -x会在执行每一行shell脚本时,把执行的内容输出来。它可以让你看到当前执行的情况,里面涉及的变量也会被替换成实际的值。

set -e会在执行出错时结束程序,就像其他语言中的“抛出异常”一样。

这两个组合在一起,可以在debug的时候替自己节省许多时间。出于防御性编程的考虑,有必要在写第一行具体的代码之前就插入它们。扪心自问,写代码的时候能够一次写对的次数有多少?大多数代码,在提交之前,通常都经历过反复调试修改的过程。与其在焦头烂额之际才引入这两个配置,不如一开始就给调试留下余地。在代码终于可以提交之后,再考虑是否保留它们也不迟。

#!/bin/sh

set -x

set -e

source mlryj.sh

echo “hello world!”

运行结果如下:

Linux shell脚本经验分享

3. shellcheck

加了set -x和set -e后,现在我已经有了shell开始的三行代码,但是具体的业务逻辑一行都没写。是不是该开始写了?

且慢!工欲善其事,必先利其器。小编先给各位介绍一个shell脚本编写神器:shellcheck

很惭愧,虽然这几年写了一些shell脚本,但是真正写起来的时候还是有很多语法记不清楚。这时候就要依仗shellcheck了。

shellcheck除了可以提醒语法问题以外,还能检查出shell脚本编写常见的错误代码。相信我,使用shellcheck会给我们的shell编写能力带来了巨大的飞跃的。

安装方法如下图:

Linux shell脚本经验分享

安装完成后可以通过shellcheck -V查看当前安装成功的版本号。如下图:

Linux shell脚本经验分享

虽然我们技能不如别人,但是我们可以升级装备,在装备上赶上并超过对方啊!有了shellcheck加持就好比真三中诸葛亮带上了飞鞋,郭嘉买了孙子兵法,哈哈哈~~

4. 注意local

首先我们来看一下下面两段代码及运行结果,代码段1:

#!/bin/bash

set -x

set -e

function wgytest()

{

a=$1

echo a

}

wgytest shell

echo “hello world!”

echo $a

运行结果如下图所示:

Linux shell脚本经验分享

代码段2:

#!/bin/bash

set -x

set -e

function wgytest()

{

local a=$1

echo a

}

wgytest shell

echo “hello world!”

echo $a

运行结果如下图所示:

Linux shell脚本经验分享

从上面的代码可以看出,我们只是将函数wgytest中的变量a加了local限定词,运行结果可以看出,第二段代码最后的echo并没有输出变量a的内容。

这是因为在bash,如果不加local限定词,变量默认都是全局的。在顶级作用域里,是否是全局变量并不重要。但是在函数里面,声明一个全局变量可能会污染到其他作用域,尤其在你根本没有注意到这一点的情况下。当我们开始把重复的逻辑提炼成函数,这时就有可能会掉到bash的这一个坑里。所以,对于在函数内声明的变量,小编的建议是记得加上local限定词。

5. 写在最后

以上几条都是具体的建议,这条来点虚的。

虽然使用shell可以方便快捷地实现各种复杂的功能,但也还是不得不依靠grep、sed、awk等各种工具把它们粘合在一起。实际上由于缺乏完善的数据结构以及一致的API,shell脚本在处理复杂的逻辑上还是显得力不从心。如果你的任务包含较为复杂的逻辑,而且数据结构复杂,那么建议使用python之类的语言编写脚本。

程序猿无论写什么代码,都要三思而行,切忌粗心大意。毕竟许多时候,我们的一个粗心就会给整个系统带来一个悲剧,其实复杂的脚本也是发端于几行小小的命令。一开始写脚本的人,也许以为它只是一次性任务。代码里难免对一些外部条件有些假定,在当时也许是正常的,但是随着外部环境的变化,这些就成了隐藏的雷。这就需要在编写的时候辨清哪些是会变的依赖、哪些是脚本正常运行所不可或缺的。同时要有防御性编程的意识,给自己的代码一道护城河。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    88

    文章

    11817

    浏览量

    219545
  • Shell
    +关注

    关注

    1

    文章

    375

    浏览量

    25486
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux Shell文本处理神器合集:15个工具+实战例子,效率直接翻倍

    Linux 系统中,文本是数据交互的 “通用语言”—— 日志文件、配置文件、数据报表、程序输出几乎都以文本形式存在。手动编辑文本不仅繁琐,还容易出错,而掌握 Shell 文本处理工具,能让你用几行命令完成批量筛选、数据提取、统计分析,甚至复杂的文本清洗。
    的头像 发表于 02-03 15:42 2721次阅读
    <b class='flag-5'>Linux</b> <b class='flag-5'>Shell</b>文本处理神器合集:15个工具+实战例子,效率直接翻倍

    从小白到大牛:Linux嵌入式系统开发的完整指南

    基础强化:嵌入式开发离不开Linux 系统操作,需熟练掌握命令行(文件操作、进程管理、权限配置)、Shell 脚本编写、Makefile 基础语法。建议通过 “每日一个 Linux
    发表于 12-16 10:42

    【瑞萨RA6E2】1.使用串口shell点亮LED灯

    啥技术含量,所以想来就打算实现一个小型的串口shell,用串口助手发指令来进行点灯,这样将串口和点灯融为一体,不至于单调乏味。 1,打开原理图 发现led1和led2分别如上图,打开rasmart软件
    发表于 11-09 17:26

    e203仿真报Syntax error: \"&amp;\"unexpected错误的原因

    “NO” 再试一下: ls -l /bin/sh 改成bash 再跑测试程序: 成功! 原因分析:dash和bash应该是shell脚本语言的两种解释方式,Ubuntu默认采用dash,导致语法错误。
    发表于 11-05 13:39

    【EASY EAI Nano-TB(RV1126B)开发板试用】命令行功能测试-shell脚本进行IO控制-红绿灯项目-实现开机起动

    0接上文【EASY EAI Nano-TB(RV1126B)开发板试用】命令行功能测试-shell脚本进行IO控制-红绿灯项目 Linux 起动系统下 init 系统大多数 Linux
    发表于 11-03 17:25

    【技术分享】正确编写SysV Init脚本以实现Systemd兼容(上)

    嵌入式的ubuntu系统如何写好SysVInit脚本呢?与system服务又有什么差别呢?一起随着文章来探究吧。问题背景许多传统Linux服务仍使用SysVInit脚本(/etc/init.d
    的头像 发表于 10-28 11:45 840次阅读
    【技术分享】正确编写SysV Init<b class='flag-5'>脚本</b>以实现Systemd兼容(上)

    shell基本介绍及常用命令之shell基本介绍

    Shell是什么?我们在刚开始接触Linux的时候,经常会听到工程师提到Shell这个词,刚开始不知道这是个干什么的,简单的说,它是一个应用,接收用户命令,调用相应的内核接口函数或应用程序,并输出
    发表于 09-28 09:05

    LuatOS脚本开发入门:嵌入式运行框架全解析!

    想搞懂LuatOS如何运行Lua脚本?本文深入剖析其嵌入式运行框架,涵盖虚拟机加载、任务协程、系统初始化等关键环节,适合初学者。 一、LuatOS 编程起步 1.1 底层固件怎么启动 LuatOS
    的头像 发表于 09-26 17:45 628次阅读
    LuatOS<b class='flag-5'>脚本</b>开发入门:嵌入式运行框架全解析!

    嵌入式开发新选择:LuatOS脚本框架入门教程

    LuatOS正成为嵌入式开发的新趋势!本教程带你从基础入手,全面了解其基于Lua的脚本开发模式与轻量级运行框架。 一、LuatOS 编程起步 1.1 底层固件怎么启动 LuatOS 脚本
    的头像 发表于 09-26 17:34 744次阅读
    嵌入式开发新选择:LuatOS<b class='flag-5'>脚本</b>框架入门教程

    Python脚本实现运维工作自动化案例

    还在为重复性运维工作而烦恼?每天被各种告警、监控、部署搞得焦头烂额?作为一名有10年经验的运维老司机,今天分享5个超实用的Python自动化脚本,让你的运维工作效率提升300%!这些都是我在生产环境中实际使用的案例,代码简洁高效,拿来即用!
    的头像 发表于 08-27 14:46 1363次阅读

    Linux服务器性能调优的核心技巧和实战经验

    如果你正在为这些问题头疼,那么这篇文章就是为你准备的!作为一名拥有10年经验的运维工程师,我将毫无保留地分享Linux服务器性能调优的核心技巧和实战经验
    的头像 发表于 08-27 14:36 1221次阅读

    Linux系统性能优化技巧

    经过10年一线运维经验,我发现大多数工程师只掌握了Linux优化的冰山一角。今天分享的这些秘技,能让你的系统性能提升200%以上!
    的头像 发表于 08-27 14:34 1150次阅读

    Shell脚本入门指南

    Shell 是一块包裹着系统核心的壳,处于操作系统的最外层,与用户直接对话,把用户的输入, 解释给操作系统,然后处理操作系统的输出结果,输出到屏幕给与用户看到结果。
    的头像 发表于 06-03 10:47 1380次阅读
    <b class='flag-5'>Shell</b><b class='flag-5'>脚本</b>入门指南

    详解Linux系统中的服务管理

    Linux中,无论何时当你安装任何带有服务和守护进程的包,系统默认会把这些服务的初始化及 systemd脚本添加进去,不过此时它们并没有被启用。
    的头像 发表于 05-23 15:10 938次阅读
    详解<b class='flag-5'>Linux</b>系统中的服务管理

    【米尔-RK3562开发板试用评测】命令行功能测试-shell脚本进行IO控制-(绿色)RUN 灯、(红色)User灯

    在板上使用shell脚本语言简单明了开发效率高便于调试修改动态性强资源利用灵活但实时性不足。 shell脚本linux中壳层与命
    发表于 05-09 18:19