【shell】代码编写规范-修改版

通用

排版规范

1、程序块要采用缩进风格编写。函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格。

  • 例:
# 文件自检
file_check()
{
   if [[ ! -n $file_01 ]];then
       echo "TM_ota.sh 文件不存在。"
       exit
   elif [[ ! -n $file_02 ]];then
       echo "TM_app.sh 文件不存在。" 
       exit
   fi
}

函数内部统一缩进一格,判断语句内部统一缩进一格。

2、不要把多个短语写在一行中,即一行只写一条语句。

  • 比如错误示范
a=1;b=2;c=$((a+b));

3、If、for、do、while、case、switch、default等语句自占一行。

4、程序块的分界符(如C++/C#语言中的‘{’和‘}’)应各自独占一行并且位于同一列,同时与引用它们的语句左对齐。

  • 3、4 都可以参考第一个例子。

5、行长度,每行不超过80个字符。以下情况除外

  • 长的导入模块语句
  • 注释里的URL

shell

一、注释

1、脚本头部注释

    脚本头部注释,主要是改脚本的描述信息,这些信息主要包括脚本的作者、开发时间、脚本的功能描述,如:

#!/bin/bash
#####################################
#Script: XXXX
#Author: XXXX
#Date: XX-XX-XX
#Description: XXXXXX
#Usage: XXXX
#####################################

其中,(根据项目实际需要,也可以添加其他描述信息)

2、其他注释
  • 函数注释:描述函数的具体功能;放在函数上一行。
  • 代码注释:对关键或复杂代码进行注释;注释放在代码上一行或代码后。

二、命名规范

1、变量名
  • 命名只能使用英文字母,数字和下划线。
  • 只有一个英文单词时使用全拼;有多个单词时,使用下划线分隔;长度较长时,可以取单词前3~4字母。
  • 避免使用Linux的保留字如true、关键字如pwd等。
  • 配置文件中定义的环境变量名统一大写。
2、函数命名

同变量命名

3、文件命名
  • linux不以文件后缀来区分文件类型,但为了便于日常管理和维护,shell脚本习惯以.sh结尾。
  • 文件名全部以小写命名,不要大小写混用(不推荐驼峰命名法,大小写混用在特殊情况下会存在问题)。
  • 文件名尽可能做到“见名知意”;可以参考变量命名。

三、函数规范

1、函数结构
  • 每一个小功能都封装到独立的函数类,一个函数只完成一个功能;在脚本尾部,通过函数的顺序调用将整个脚本逻辑串联起来。
  • 控制函数的大小,函数体的行数尽量控制在100行左右;过大的函数要分割成两个或者多个函数。
2、函数复用
  • 多次调用的功能要抽离出独立的函数,提高编码效率,降低维护成本。
  • 对常用的功能(如计算日期,发邮件、写日志)的功能,封装成函数后形成独立的脚本,其他脚本引入即可。

四、编写规范

1、缩进

    良好的缩进可以提高代码的可读性,建议代码中统一用制表符(一般4个字符)作为缩进。

2、分割长行

    参考通用部分

3、分离符合体

     主要是针对 if语句、while语句,参考通用部分

# 连续录像压力测试
test_case_02()
{
        clear
        echo "开始连续录像压力测试:"
        while((1))
        do
                echo "Loop "$i
                takevideo
                sleep 2
                echo "take video success ..."
                sleep 1
                echo " "
                ((i++))
        done
}
4、变量统一管理
  • shell脚本中使用的全局变量,要统一定义。一般在init()函数中进行统一初始化。
  • 函数内部使用的变量,最好也在函数开始位置进行初始化。
  • 函数内部局部变量用local修饰。
  • 多个脚本都需要引用的变量,统一在配置文件中定义(后续会详细说明)。
  • 变量引用,以 ${} 方式。
5、shell脚本结构

shell 脚本,自上而下一次为:

  • set_env() 该函数用于初始化脚本的环境,引入全局变量。
  • init() 该脚本用于初始化当前脚本的全局参数。
  • xxx() 其他脚本,与具体业务相关。
  • 依次调用自上而下的脚本,形成处理逻辑。

五、脚本复用

  • 将常用功能封装成函数,把一类功能的函数写入一个脚本中,其他脚本在需要某一类功能时,直接引入该脚本,调用函数即可。
  • 形成固定的脚本引用方式,如脚本开头固定引入某些脚本,达到设置脚本运行环境的功能。

Python

一、编写规范

1、分号

不要在行尾加分号, 也不要用分号将两条命令放在同一行

2、行长度

每行不超过80个字符
以下情况除外:

  • 长的导入模块语句
  • 注释里的URL

推荐:

foo_bar(self,width,height,color='black',design=None,x='foo',

             emphasis=None,highlight=0)

     if(width ==0andheight ==0and

         color =='red'andemphasis =='strong'):

如果一个文本字符串在一行放不下, 可以使用圆括号来实现隐式行连接:

x =('这是一个非常长非常长非常长非常长'

     '非常长非常长非常长非常长非常长非常长的字符串')

在注释中,如果必要,将长的URL放在一行上。

Yes: # See details at

      # [http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html](http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html)

No: # See details at

     # [http://www.example.com/us/developer/documentation/api/content/\](http://www.example.com/us/developer/documentation/api/content/)

     # v2.0/csv_file_name_extension_full_specification.html

注意上面例子中的元素缩进; 你可以在本文的:ref:缩进<indentation>`部分找到解释.

3、括号

    宁缺毋滥的使用括号
    除非是用于实现行连接, 否则不要在返回语句或条件语句中使用括号. 不过在元组两边使用括号是可以的.

Yes: if foo:
         bar()
     while x:
         x = bar()
     if x and y:
         bar()
     if not x:
         bar()
     return foo
     for (x, y) in dict.items(): ...
No:  if (x):
         bar()
     if not(x):
         bar()
     return (foo)
4、缩进

    用4个空格来缩进代码
    绝对不要用tab, 也不要tab和空格混用. 对于行连接的情况, 你应该要么垂直对齐换行的元素(见 :ref:行长度 <line_length> 部分的示例), 或者使用4空格的悬挂式缩进(这时第一行不应该有参数):

Yes:   # 与起始变量对齐
       foo = long_function_name(var_one, var_two,
                                var_three, var_four)
 
       # 字典中与起始值对齐
       foo = {
           long_dictionary_key: value1 +
                                value2,
           ...
       }
 
       # 4 个空格缩进,第一行不需要
       foo = long_function_name(
           var_one, var_two, var_three,
           var_four)
 
       # 字典中 4 个空格缩进
       foo = {
           long_dictionary_key:
               long_dictionary_value,
           ...
       }
No:    # 第一行有空格是禁止的
      foo = long_function_name(var_one, var_two,
          var_three, var_four)
 
      # 2 个空格是禁止的
      foo = long_function_name(
        var_one, var_two, var_three,
        var_four)
 
      # 字典中没有处理缩进
      foo = {
          long_dictionary_key:
              long_dictionary_value,
              ...
      }
5、空行

    顶级定义之间空两行, 方法定义之间空一行
    顶级定义之间空两行, 比如函数或者类定义. 方法定义, 类定义与第一个方法之间, 都应该空一行. 函数或方法中, 某些地方要是你觉得合适, 就空一行.

6、空格

按照标准的排版规范来使用标点两边的空格
括号内不要有空格.
按照标准的排版规范来使用标点两边的空格

Yes: spam(ham[1], {eggs: 2}, [])
No:  spam( ham[ 1 ], { eggs: 2 }, [ ] )

不要在逗号, 分号, 冒号前面加空格, 但应该在它们后面加(除了在行尾).

Yes: if x == 4:
         print x, y
     x, y = y, x
No:  if x == 4 :
         print x , y
     x , y = y , x

参数列表, 索引或切片的左括号前不应加空格.

Yes: spam(1)
no: spam (1)
Yes: dict['key'] = list[index]
No:  dict ['key'] = list [index]

在二元操作符两边都加上一个空格, 比如赋值(=), 比较(==, <, >, !=, <>, <=, >=, in, not in, is, is not), 布尔(and, or, not). 至于算术操作符两边的空格该如何使用, 需要你自己好好判断. 不过两侧务必要保持一致.

Yes: x == 1
No:  x<1

当'='用于指示关键字参数或默认参数值时, 不要在其两侧使用空格.

Yes: def complex(real, imag=0.0): return magic(r=real, i=imag)
No:  def complex(real, imag = 0.0): return magic(r = real, i = imag)

不要用空格来垂直对齐多行间的标记, 因为这会成为维护的负担(适用于:, #, =等):

Yes:
     foo = 1000  # 注释
     long_name = 2  # 注释不需要对齐
 
     dictionary = {
         "foo": 1,
         "long_name": 2,
         }
No:
     foo       = 1000  # 注释
     long_name = 2     # 注释不需要对齐
 
     dictionary = {
         "foo"      : 1,
         "long_name": 2,
         }

二、注释

1、块注释

    “#”号后空一格,段落件用空行分开(同样需要“#”号)

# 块注释
# 块注释
# 
# 块注释
# 块注释
2、行注释

    至少使用两个空格和语句分开,注意不要使用无意义的注释

# 正确的写法
x = x + 1  # 边框加粗一个像素

# 不推荐的写法(无意义的注释)
x = x + 1 # x加1
3、建议
  • 在代码的关键部分(或比较复杂的地方), 能写注释的要尽量写注释
  • 比较重要的注释段, 使用多个等号隔开, 可以更加醒目, 突出重要性
app = create_app(name, options)


# =====================================
# 请勿在此处添加 get post等app路由行为 !!!
# =====================================


if __name__ == '__main__':
    app.run()
4、文档注释

    作为文档的Docstring一般出现在模块头部、函数和类的头部,这样在python中可以通过对象的doc对象获取文档. 编辑器和IDE也可以根据Docstring给出自动提示

  • 文档注释以 """ 开头和结尾, 首行不换行, 如有多行, 末行必需换行, 以下是Google的docstring风格示例
# -*- coding: utf-8 -*-
"""Example docstrings.

This module demonstrates documentation as specified by the `Google Python
Style Guide`_. Docstrings may extend over multiple lines. Sections are created
with a section header and a colon followed by a block of indented text.

Example:
    Examples can be given using either the ``Example`` or ``Examples``
    sections. Sections support any reStructuredText formatting, including
    literal blocks::

        $ python example_google.py

Section breaks are created by resuming unindented text. Section breaks
are also implicitly created anytime a new section starts.
"""
  • 不要在文档注释复制函数定义原型, 而是具体描述其具体内容, 解释具体参数和返回值等
#  不推荐的写法(不要写函数原型等废话)
def function(a, b):
    """function(a, b) -> list"""
    ... ...


#  正确的写法
def function(a, b):
    """计算并返回a到b范围内数据的平均值"""
    ... ...
  • 对函数参数、返回值等的说明采用numpy标准, 如下所示
def func(arg1, arg2):
    """在这里写函数的一句话总结(如: 计算平均值).

    这里是具体描述.

    参数
    ----------
    arg1 : int
        arg1的具体描述
    arg2 : int
        arg2的具体描述

    返回值
    -------
    int
        返回值的具体描述

    参看
    --------
    otherfunc : 其它关联函数等...

    示例
    --------
    示例使用doctest格式, 在`>>>`后的代码可以被文档测试工具作为测试用例自动运行

    >>> a=[1,2,3]
    >>> print [x + 3 for x in a]
    [4, 5, 6]
    """
  • 文档注释不限于中英文, 但不要中英文混用
  • 文档注释不是越长越好, 通常一两句话能把情况说清楚即可
  • 模块、公有类、公有方法, 能写文档注释的, 应该尽量写文档注释

三、语句

    通常每个语句应该独占一行
    不过, 如果测试结果与测试语句在一行放得下, 你也可以将它们放在同一行. 如果是if语句, 只有在没有else时才能这样做. 特别地, 绝不要对 try/except 这样做, 因为try和except不能放在同一行.

Yes:
 
  if foo: bar(foo)
No:
 
  if foo: bar(foo)
  else:   baz(foo)
 
  try:               bar(foo)
  except ValueError: baz(foo)
 
  try:
      bar(foo)
  except ValueError: baz(foo)

四、命名

  • 应该避免的名称
  1. 单字符名称, 除了计数器和迭代器.
  2. 包/模块名中的连字符(-)
  3. 双下划线开头并结尾的名称(Python保留, 例如init)
  • 命名约定
  1. 所谓"内部(Internal)"表示仅模块内可用, 或者, 在类内是保护或私有的.
  2. 用单下划线(_)开头表示模块变量或函数是protected的(使用import * from时不会包含).
  3. 用双下划线(__)开头的实例变量或方法表示类内私有.
  4. 将相关的类和顶级函数放在同一个模块里. 不像Java, 没必要限制一个类一个模块.
  5. 对类名使用大写字母开头的单词(如CapWords, 即Pascal风格), 但是模块名应该用小写加下划线的方式(如lower_with_under.py). 尽管已经有很多现存的模块使用类似于CapWords.py这样的命名, 但现在已经不鼓励这样做, 因为如果模块名碰巧和类名一致, 这会让人困扰.

Python之父Guido推荐的规范

Type Public Internal
Modules lower_with_under _lower_with_under
Packages lower_with_under
Classes CapWords _CapWords
Exceptions CapWords
Functions lower_with_under() _lower_with_under()
Global/Class Constants CAPS_WITH_UNDER _CAPS_WITH_UNDER
Global/Class Variables lower_with_under _lower_with_under
Instance Variables lower_with_under _lower_with_under (protected) or __lower_with_under (private)
Method Names lower_with_under() _lower_with_under() (protected) or __lower_with_under() (private)
Function/Method Parameters lower_with_under
Local Variables lower_with_under
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容