记一次符合Google Coding Style的Bash脚本重构

news/2024/10/30 11:26:45/

最近我在思考这样一个问题,顺便看一下gpt对这个问题的解释。搜索发现:

团队写代码,为什么要遵循coding guideline?

  1. 一致性:编码准则确保整个团队的代码风格和格式是一致的,这使得团队成员之间更易于交流和协作。这也使得代码更容易维护和更新,因为其他人可以更轻松地理解代码。
  2. 可读性:编码准则有助于提高代码的可读性。通过对代码进行格式化和注释,代码会更易于阅读和理解,从而减少错误和缺陷,并提高代码的质量。
  3. 可维护性:编码准则有助于提高代码的可维护性。通过使用一致的格式和风格,团队成员可以更轻松地理解代码,并进行更快速的故障排除和修复。
  4. 代码质量:编码准则有助于提高代码的质量。通过要求团队成员编写可读性高、可维护性强的代码,编码准则可以确保代码更加健壮、可靠和安全。这也有助于减少代码缺陷和错误,提高代码的可靠性和可用性。
  5. 代码重用:编码准则有助于提高代码的重用性。通过编写符合标准的代码,团队成员可以更容易地将代码重用在其他项目中,从而提高生产力和效率。

继续搜索:

对于一个使用bash为主要语言的项目,业界推荐的coding guideline?

  1. 使用有意义的变量名:变量名应该具有描述性,以便其他人可以轻松地理解代码。
  2. 缩进:使用4个空格作为缩进,而不是制表符。
  3. 注释:对代码进行注释,以解释代码的目的和功能。注释应该清晰、简洁,并且易于阅读。
  4. 函数:编写短小精悍的函数,每个函数都应该具有一个特定的目的。函数应该使用有意义的名称,并且应该清晰地描述其目的和功能。
  5. 错误处理:在代码中包含错误处理,以确保代码在遇到错误时不会崩溃或产生不可预测的结果。
  6. 使用双引号:在引用变量时,使用双引号而不是单引号,以确保变量扩展能够正常工作。
  7. 使用全局变量:尽量避免使用全局变量,因为它们很难调试和维护。
  8. 使用命令替换:使用$()语法而不是反引号 ``来执行命令替换。
  9. 使用数组:使用数组来管理相关变量,而不是使用多个单独的变量。
  10. 使用“set -u”:使用“set -u”来检查未定义的变量,以避免在引用未定义的变量时产生错误。

这些规范有助于提高 Bash 代码的可读性、可维护性和可靠性。
然后我搜索 “bash script style guideline”,最上面的结果是:
在这里插入图片描述

即代码规范:https://google.github.io/styleguide/shellguide.html
我仔细阅读了这份风格指南,对其中的“局部变量”的章节很感兴趣。
文中说:「最好把局部变量的定义与赋值,换行实现,不要写到同一行上」,以免掩盖报错状态码。
原文

Declare function-specific variables with local. Declaration and assignment should be on different lines.
Ensure that local variables are only seen inside a function and its children by using local when declaring them. This avoids polluting the global name space and inadvertently setting variables that may have significance outside the function.
Declaration and assignment must be separate statements when the assignment value is provided by a command substitution; as the local builtin does not propagate the exit code from the command substitution.

我动手验证这个细节,发现果然如此:
在这里插入图片描述

然后我开始自查当前的项目,寻找类似于如下风格的代码:

local my_var="$(my_func)"

优化后的预期结果:

local my_var
my_var="$(my_func)"

在 https://regex101.com/ 测试代码的运行。给出范例

regex:  local fn=$(echo $name_ver| tr ':' '-').tar.xz
test stringlocal fn=$(echo $name_ver| tr ':' '-').tar.xz     #普通local fn=$(echo $name_ver| tr ':' '-').tar.xz   # 模拟多个空格local fn=$(echo $name_ver| tr ':' '-').tar.xz       # 模拟tab缩进local fn="$(echo $name_ver| tr ':' '-').tar.xz" # 模拟带引号的变量声明

测似乎生成的代码

$1local $2\n$1$2=$3

生成的代码

$re = '/^(\s*)local\s+(\w+)=("?\$\(.*)/m';
$str = '  local fn=$(echo $name_ver| tr \':\' \'-\').tar.xztlocal fn=$(echo $name_ver| tr \':\' \'-\').tar.xztlocal fn=$(echo $name_ver| tr \':\' \'-\').tar.xzlocal fn="$(echo $name_ver| tr \':\' \'-\').tar.xz"';
$subst = "$1local $2\n$1$2=$3";$result = preg_replace($re, $subst, $str);echo "The result of the substitution is ".$result;

精简为 perl_oneliner:
在这里插入图片描述

perl -pe 's/^(\s*)local\s+(\w+)=("?\$\(.*)/$1local $2\n$1$2=$3/g' -i file.txt

测试的场景:
搜索代码

pcregrep -lr '^(\s*)local\s+(\w+)=("?\$\(.*)' *

批量修正:

perl -pi -e 's#^(\s*)local\s+(\w+)=("?\$\(.*)#$1local $2\n$1$2=$3#' $(pcregrep -l -r '^(\s*)local\s+(\w+)=("?\$\(.*)' * )

修正之后,仔细阅读diff,检验效果,发现符合预期。

后续:增加git hook检测代码

为了让以后新增的代码,也都符合上述规范,我增加了这样一个 pre-commit脚本。这样,每次提交之前,它都会帮我确保代码合规。

同时,我在编辑器里,设置了shfmt、shellcheck之类的规范,并设置为format on save,即保存时自动格式化,来自动处理格式问题。

# test code 
if ! grep -wq 'Code violates rules' .git/hooks/pre-commit; then
cat >> .git/hooks/pre-commit <<'GIT_PRE_COMMIT_EOF'                                                                                                                                        
#!/usr/bin/env bash
if find . -name '*.sh'| xargs pcregrep '^\s+local\s+\w+="?(`|\$\()'; thenecho "Error: Code violates rules"echo 'use: local var'echo 'var="$(...")'echo 'instead of local var=``'echo 'or local var="$(...)"'echo 'as of explained in https://google.github.io/styleguide/shellguide.html'exit 1
fi
GIT_PRE_COMMIT_EOF
chmod +x .git/hooks/pre-commit
fi

总结:

  • 寻找业界规范
  • 遵循规范
  • 修改过去不合规范的代码
  • 新增代码确保合规
  • 将代码的规范检查,加入到日常的流程里。(goimport check)
  • 越早做,历史包袱越少。越晚做,历史包袱越沉重。
  • related PR: https://git.yunion.io/projects/CLOUD/repos/yunion-build/pull-requests/1355/diff#main.sh

links

  • Checks · koalaman/shellcheck Wiki
  • ShellCheck - A shell script static analysis tool
  • styleguide | Style guides for Google-originated open-source projects*
  • regex101: build, test, and debug regex

以上是文章的主要内容,作为融合云/多云管理/私有云/FinOps 厂商,云联壹云会持续关注这些领域的动态,分享相关的信息和技术,可以通过的官网(yunion.cn)或关注的公众号(云联壹云)来获取最新的信息,感谢大家的时间。

原文地址:https://www.yunion.cn/article/html/20230524.html

其他推荐阅读

云联壹云融合云管理平台的 10 大应用场景
SkyPilot:构建在多云之上的ML和数据科学,可节约3倍以上成本
Flexera 2023 云状态报告解读
新品发布 | Cloudpods 3.10版本上线!
企业面对FinOps,到底能做些什么?总结了4个方面


http://www.ppmy.cn/news/83133.html

相关文章

Spring Boot 中如何使用 Spring Cloud Alibaba 实现微服务治理

Spring Boot 中如何使用 Spring Cloud Alibaba 实现微服务治理 在现代化的微服务架构中&#xff0c;服务的数量和复杂度越来越高&#xff0c;如何有效地管理这些服务变得越来越重要。Spring Cloud Alibaba 提供了一套完整的微服务治理解决方案&#xff0c;包括服务注册与发现、…

数字化转型-基于连接和共生的价值再创造

数字化转型是当今商业领域中一个持续引起关注的话题。随着科技的不断发展&#xff0c;企业不得不重新思考他们的业务模式&#xff0c;并采取适应数字化时代的策略。在数字化转型的过程中&#xff0c;连接和共生的价值再创造成为了一个重要的关键点。 连接是指通过技术手段将不同…

可以在商场内部使用的导航地图?商场导览图怎么画?

可以在商场内部使用的导航地图&#xff1f;随着商业的发展&#xff0c;商场和商业综合体的规模越来越大&#xff0c;在注重消费者购物体验的时代&#xff0c;消费者想方便地找到心仪的品牌或美食&#xff0c;商场内具有“导示”作用的标志很重要。导示系统具有引导、说明、指示…

【RocketMQ】RocketMQ入门

【RocketMQ】RocketMQ入门 文章目录 【RocketMQ】RocketMQ入门1. 消费模式2. 发送/消费 消息2.1 同步消息2.2 异步消息2.3 单向消息2.4 延迟消息2.5 批量消息2.6 顺序消息 1. 消费模式 MQ的消费模式大致分为两种&#xff0c;一种是推Push&#xff0c;一种是拉pull。 Push模式…

Install Prometheus Monitoring On Kubernetes Cluster

目录 Node & Software & Docker Images Lists ​Prometheus introduction Download Kubernetes Prometheus Manifest Files Install Prometheus Monitoring Kubernetes Create a Namespace Create a Cluster Role And Binding It Create a Config Map Create…

R语言实践——rWCVP 的函数清单

rWCVP 的函数清单 1. get_area_name()用法参数值详介例子 2. get_wgsrpd3_codes()用法参数值详介例子 3. powo_map()用法参数值 4. powo_pal(), scale_color_powo(), scale_colour_powo(), scale_fill_powo()用法参数值 5. redlist_example用法格式资源 6. taxonomic_mapping用…

1139 First Contact (PAT甲级)

这道题柳婼有个很巧妙的方法&#xff0c;就是如果a和b是朋友&#xff08;a, b都是四位数字id&#xff09;&#xff0c;那就把a * 10000 b和b * 10000 a都map到1&#xff0c;那就很容易判断两个人是否朋友了。 #include <cstdio> #include <iostream> #include &…

盛元广通疾病预防控制中心检测管理信息系统

近些年&#xff0c;在疾病预防控制领域&#xff0c;公共卫生事件的发生都是通过信息化手段在日常工作中加以应用以及广泛深入的探索&#xff0c;加快疾控实验室信息化建设进程&#xff0c;可以有效把控不同类型检测任务中的每个节点&#xff0c;严防不同系统填报多次出现信息误…