Files
team-work/2.Linux Shell 脚本编程最佳实践.md

5.8 KiB
Raw Permalink Blame History

前言

为什么要有规范

编码规范对于程序员而言尤为重要,有以下几个原因:

  • 一个软件的生命周期中80%的花费在于维护

  • 几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护

  • 编码规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的代码

  • 如果你将源码作为产品发布,就需要确任它是否被很好的打包并且清晰无误,一如你已构建的其它任何产品

编码规范原则

本文档中的准则致力于最大限度达到以下原则:

  • 正确性

  • 可读性

  • 可维护性

  • 可调试性

  • 一致性

  • 美观

尽管本文档涵盖了许多基础知识,但应注意的是,没有编码规范可以为我们回答所有问题,开发人员始终需要再编写完代码后,对上述原则做出正确的判断。

用什么样的 SHELL

BASH 应该是唯一的 SHELL 脚本解释器。因为绝大多数GNU/Linux默认安装的Shell都是bash考虑到可移植性。SHELL脚本一般用BASH解释器来执行。

对于 #!/bin/bash ,大多数写过脚本的人都知道,这是命令解释器的声明,通常位于脚本的第一行,它有个专业的名字,叫做 shebang ,作为对命令解释器的声明,#!/bin/bash 声明了 bash 程序所在的路径。

有了命令解释器的路径声明,那么当执行该脚本时,系统就知道该去哪里找这个命令解释器,也就是 Shebang 中指定的 bash 。

同理,#!/bin/sh 也是一样的,包括非 Shell 脚本,如 #!/usr/bin/python 也是同理,都是声明命令解释器的位置。

[opc@instance-20210621-0038 ~]$
[opc@instance-20210621-0038 ~]$ ls -al /bin/bash
-rwxr-xr-x. 1 root root 964536 Nov 22  2019 /bin/bash
[opc@instance-20210621-0038 ~]$
[opc@instance-20210621-0038 ~]$
[opc@instance-20210621-0038 ~]$ /bin/bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[opc@instance-20210621-0038 ~]$
[opc@instance-20210621-0038 ~]$ ls -al /bin/sh
lrwxrwxrwx. 1 root root 4 May 13  2021 /bin/sh -> bash
[opc@instance-20210621-0038 ~]$

#!/usr/bin/env bash ,网上经常可以看到还有这种 shebang 写法

env 命令用于显示系统中已存在的环境变量,以及在定义的环境中执行指令

这种 shebang 写法的原理是:当执行 env bash 时,它其实会去操作系统的$PATH环境变量的路径中去查找bash可执行文件。

  • #!/bin/bash 是直接指定把bash可执行文件的路径硬编码到shebang

  • #!/usr/bin/env bash 则是告诉系统去 $PATH 包含的目录中挨个去找吧,先找到哪个,就用哪个

#!/usr/bin/env bash 优缺点

优点

  • #!/usr/bin/env bash 不必在系统的特定位置查找命令解释器,为多系统间的移植提供了极大的灵活性和便利性(某些系统的一些命令解释器并不在 /bin 或 一些约定的目录下,而是一些比较奇怪的目录)

  • 在不了解主机的环境时,#!/usr/bin/env bash 写法可以使开发工作快速地展开。

缺点

  • #!/usr/bin/env bash 在对安全性比较看重时,该写法会出现安全隐患

    #!/usr/bin/env bash 从 $PATH 中查找命令解释器所在的位置并匹配第一个找到的位置,这意味着可以伪造一个假的命令解释器(如自己写一个假的 bash并将伪造后的命令解释器所在目录写入 PATH 环境变量中并位于靠前位置,这样,就形成了安全隐患。而 /bin 由于一般只有 root 用户才有操作权限,所以,#!/bin/bash 这种写法相对较为安全。

  • #!/usr/bin/env 无法传递多个参数(这是由于 Shebang 解析造成的,并非 env 命令的缘故)

如: #!/usr/bin/perl -w #!/bin/csh -f 而如果使用 #!/usr/bin/env perl -w 这种写法的话,perl -w 会被当成一个参数,于是,根本找不到 perl -w 这个命令解释器,就会出错。

#!/bin/bash 优缺点

优点

  • 准确指出所需命令解释器的位置

  • 安全性相对较高

  • 可以传递多个参数

缺点

  • 移植性相对较差,很多系统的命令解释器位置不一致

  • 一些命令解释器的位置记不住

到底用哪个

  • 两个都可以

  • 如果对安全性比较看重,使用 #!/bin/bash

  • 如果对安全性不是很看重,但对移植性(灵活性)比较看重,使用 #!/usr/bin/env bash

  • 看自己的意愿,喜好

什么时候用 SHELL

源文件

文件名称和文件编码

文件名命名规范

可执行文件不建议有扩展名,库文件必须使用 .sh 作为扩展名,且应是不可执行的。

执行一个程序时无需知道其编写语言且shell脚本并不要求具有扩展名所以更倾向可执行文件没有扩展名。

而库文件知道其编写语言十分重要,使用 .sh 作为特定语言后缀的扩展名,可以和其他语言编写的库文件加以区分。

文件名要求全部小写, 可以包含下划线 _ 或连字符 -, 建议可执行文件使用连字符,库文件使用下划线。

文件编码规范

源文件编码格式为UTF-8。 避免不同操作系统对文件换行处理的方式不同一律使用LF。

单行长度

每行最多不超过120个字符。每行代码最大长度限制的根本原因是过长的行会导致阅读障碍使得缩进失效。

除了以下两种情况例外:

  • 导入模块语句

  • 注释中包含的URL

如出现长度必须超过120个字符的字符串应尽量使用here document或者嵌入的换行符等合适的方法使其变短。

SUID/SGID