Shell编程心得

761 阅读4分钟

前言

随着技术的发展,虽然出现了许多现代的编程语言,但Shell编程由于其独特的优势——简洁性、高效性和在Linux系统中的无处不在,仍然保持着其重要性。

以下是笔者多年积累的一些Shell编程心得,这些心得涵盖了从基础语法到高级功能的各个方面,无论是初学者还是有经验的开发者,都可以从中受益。通过这些心得,你将能够编写出更加高效、健壮且易于维护的Shell脚本,为你的自动化任务和系统管理工作带来便利。

符合代码规范

shell文件开头有以”#!”开头的注释,学名Shebang,也称为Hashbang、“蛇棒”,如:

#!/bin/sh

如果编写的a.sh没有开头的注释,执行 ./a.sh时系统会默认用$SHELL指定的解释器,因解释器的兼容性等问题,会出现一些不可预料的问题。

image-20231224140321085

Centos7.6 相关内容示例

推荐写法:

#!/usr/bin/env bash

代码有注释

注释的作用是让代码可读性更强,方便维护人员快速上手;也方便编写人员逻辑梳理。

一般包含以下几部分:

  1. Shebang
  2. 文件头
  3. 脚本的参数
  4. 脚本的用途
  5. 脚本的注意事项
  6. 脚本的写作时间,作者,版权等

例如:

image-20231224143718031

  • 各个函数前的说明注释

  • 一些较复杂的单行命令注释

参数要规范

  • 如果脚本需要接收参数,需要进行合理判断和处理
  • 需要合适的回显,方便使用者了解参数的使用

最简单的参数个数判断示例

if [[ $## != 2 ]];then
    echo "Parameter incorrect."
    exit 1
fi 

变量和魔鬼数字

变量大写加下划线在文件头部定义

如:

## configurations
CODE_PATH="/root/work/workspace/og-apus/og-apus"
OGAPUS_RELEASE_FOLDER="/root/work/workspace/og-apus/release"
OGSP4_BUILD_PATH="/root/work/ogsp4-release-env/base/images"
OGAPUS_RELEASE_PATH_ON_PDD="/pdd-release/og-apus/docker-images"

避免魔鬼数字,如果必须使用数字,请用变量定义,并注意变量名称可读性,适当添加变量定义注释。

缩进有规矩

推荐使用工具自动格式化,vscode + shell-format插件

两种缩进类型:

  • soft tab:就是使用n个空格进行缩进(n通常是2或4)
  • hard tab:指真实的"\t"制表符字符

不评论优劣,推荐两个空格

命名有标准

  • 文件名规范,以.sh结尾,方便识别
  • 变量名字要有含义,不要拼错
  • 统一命名风格,shell一般用小写字母加下划线,不建议使用驼峰命名。

编码要统一

  • 请使用UTF-8编码格式
  • 如编码格式不正确,可使用命令 dos2unix a.sh进行格式修复

常见问题:windows下未专门配置过utf8为默认编码格式的编辑器,回车换行是 \r\n, utf8下是\n

文件可执行权限

  • 不加可执行权限: bash a.sh
  • 加可执行权限: ./a.sh

常见的出错是通过 ./a.sh执行,但是未对a.sh赋予可执行权限。

错误处理和调试

  • 实现适当的错误处理机制,如使用 set -e 以在命令失败时停止执行。

  • 使用 set -x 来调试脚本,了解执行流程。

  • 标准文档要有标准日志输出

回显

  • 回显必要信息给使用者,方便判断进度、问题等
  • 时间信息,关键事件/状态
  • 可通过颜色、闪烁等效果突出特定回显内容

密码要移除

!!!不要把密码放在脚本里,尤其是公用代码仓库时!!!

太长要分行

使用反斜杠分行,如:

./configure \
–prefix=/usr \
–sbin-path=/usr/sbin/nginx \
–conf-path=/etc/nginx/nginx.conf \

勤用引号

  • 推荐在使用”$”来获取变量的时候最好加上双引号
  • 注意单双引号的区别:
    • 双引号内部有转义符的内容会被转义
    • 单引号原样输出,即使有转义符也不做转义,直接输出

参考:

[ ]: www.shellcheck.net/wiki/SC2086 "SC2086"

使用新写法

  • 尽量使用func( ){ }来定义函数,而不是func{ }
  • 尽量使用[[ ]]来代替[ ]
  • 尽量使用$()将命令的结果赋给变量,而不是反引号在复杂的场景下尽量使用## #printf代替echo进行回显

image-20231224143407192

数值计算

expr 和 (()),推荐用(()),原因是执行效率高很多倍

文件结构

## 头部: 
## 参数处理,变量定义
## --------
## 函数部分:函数定义
## --------
## 执行逻辑
## 调用函数的逻辑顺序

SUID SGID SBIT

  • 脚本中禁止使用文件特殊权限操作

参考:Linux文件特殊权限SUID、SGID与SBIT-腾讯云开发者社区-腾讯云

勤查资料

  • Shell编程没有难度,主要是习惯的养成和知识点的积累,用的多了,思考的多了,写起来就得心应手
  • 知识点容易遗忘,遇到了顺手查,养成习惯

勤练习、勤分享

偷懒,某种程度上是推动人类进步的一种力量

  • 脚本的核心思想,把复杂问题分解成简单的小问题,把重复性人力劳动通过代码脚本实现,同时借助Linux的Crontab定时机制,可以处理很多实际的问题和需求
  • 除工作任务外,善于发现可”偷懒“的场景,善于发现可通过脚本、工具提炼的场景,动手练习,推广试用,反馈改进,持续提升
  • 坚信:三人行必有我师,勤分享勤讨论,能碰撞出不一样的灵感和收获

【星猿杂谈】:在这里我们共同探索科技新趋势,分享积累的点滴,从编程语言到系统架构,从人工智能到高性能计算,我们追求技术的进步,同时珍视分享的力量。欢迎关注我们,在技术的精彩世界中一起遨游,发现更多未知!