像专业人士一样编写 Bash 脚本 - 第一部分 - 样式指南

2025-05-28

像专业人士一样编写 Bash 脚本 - 第一部分 - 样式指南

如果您不了解Bash 的“怪癖”和“特权”,编写脚本可能会很困难。在我的母语中,我们使用意第绪语中的“怪癖”和“特权”来表示;它被称为“Shtickim”( “Shtick”的复数形式)。您准备好了解更多关于 Bash 的“Shtickim”了吗?

这篇博文是我正在撰写的系列文章之一,目的是为将来容易忘事的我保存知识,帮助新同事,也为了满足像你这样渴望像我一样热爱 Bash 的程序员们。那么,我们开始吧,好吗?

它是一种脚本语言

重要的是要记住,Bash 是一种脚本语言,这意味着它不提供编程语言必须提供的标准功能,例如:

正如你已经猜到的,“Bash 程序员”(如果真有这种人的话)面临着许多挑战。以上列出的只是冰山一角。

以下是与我有相同感受的精彩博客文章:

既然我们已经讨论了我爱上 Bash 的事实,我想与你们分享这种感觉;开始吧。

变量命名约定

以下是我在 Bash 脚本中命名变量的方法

类型 范围 习俗
环境 全球的 我的变量
全球的 全球的 _我的_变量
当地的 功能 我的变量

在我之前的 Bash 脚本中,变量的名称很难理解。改用这个命名约定对我理解变量的作用域及其用途有很大帮助。

良好氛围应用

当然,我们必须看到一些实际的例子,下面是我在good_vibes.sh应用程序中实现上述命名约定的方法。

good_vibes.sh

#!/usr/bin/env bash
# ^ This is called a Shebang
# I'll cover it in future blog posts


# Global variables are initialized by Env Vars.
# I'm setting a default value with "${VAR_NAME:-"DEFAULT_VALUE"}"
_USER_NAME="${USER_NAME:-"$USER"}"
_USER_AGE="${USER_AGE:-""}"


complement_name(){
  local name="$1"
  echo "Wow, ${name}, you have a beautiful name!"
}


complement_age(){
  local name="$1"
  local age="$2"
  if [[ "$age" -gt "30" ]]; then
    echo "Seriously ${name}? I thought you were $((age-7))"
  else
    echo "Such a weird age, are you sure it's a number?"
  fi
}


main(){
  # The only function that is not "pure"
  # This function is tightly coupled to the script
  complement_name "$_USER_NAME"
  complement_age "$_USER_NAME" "$_USER_AGE"
}


# Invokes the main function
main
Enter fullscreen mode Exit fullscreen mode

good_vibes.sh - Execution and output

export USER_NAME="Julia" USER_AGE="36" && \
bash good_vibes.sh

# Output
Wow, Julia, you have a beautiful name!
Seriously Julia? I thought you were 29
Enter fullscreen mode Exit fullscreen mode

让我们将good_vibes.sh应用程序分解为可以在脚本中实现的“一组规则”。

代码块间距

每个代码块之间的两 (2) 个空白行使脚本更具可读性。

缩进

我使用了两个空格,但使用四个空格缩进也是完全没问题的。只要确保不要混淆即可。

花括号

如果是${VARIABLE} concatenated with string,请使用花括号,因为它更易于阅读。

如果是的话,那就"$LONELY_VARIABLE"没有必要了,因为它会帮助你更快地意识到它是否“孤独”。

花括号的主要用途是执行Shell 参数扩展,如全局变量初始化部分所示。

方括号

使用双方括号可以更轻松地阅读条件代码块。但是,请注意, Shell sh[[ ]]不支持使用双方括号;您应该使用单方括号[ ]

为了证明可读性,这里有一个“复杂”的条件代码块:

if [[ "$USER_NAME" = "Julia" || "$USER_NAME" = "Willy" ]] \
   && [[ "$USER_AGE" -gt "30" ]]; then
  echo "Easy to read right?"
fi

# Mind that `||` is replaced with `-o`, see https://acloudguru.com/blog/engineering/conditions-in-bash-scripting-if-statements
# Thank you William Pursell
if [ "$USER_NAME" = "Julia" -o "$USER_NAME" = "Willy" ] \
   && [ "$USER_AGE" -gt "30" ]; then
  echo "No idea why but I feel lost with single brackets."
fi
Enter fullscreen mode Exit fullscreen mode

如果你还没注意到,你刚刚学到了||代表OR&&代表AND。而简短的-gt表达式表示greater than使用数字时的情况。最后,该\字符允许分行,从而使代码更具可读性。

技巧:使用\多余的空格\ <- extra space可能会导致奇怪的错误。请确保 后面没有空格\

我认为使用[[ ]]感觉更直观,因为大多数条件命令都是双倍的&& ||

变量初始化

全局变量用环境变量初始化,如果环境变量为空,则设置默认值。

正如good_vibes.sh评论中提到的,我正在设置一个默认值

"${VAR_NAME:-"DEFAULT_VALUE"}"
Enter fullscreen mode Exit fullscreen mode

上面的代码片段中,文本DEFAULT_VALUE是硬编码的,可以用变量替换。例如

_USER_NAME="${USER_NAME:-"$USER"}"
Enter fullscreen mode Exit fullscreen mode

函数和局部函数变量

函数名称和local函数变量名称均为snake_cased。您也可以将函数名称更改为lowerCamelCase,当然,您可以自行决定。

将函数与脚本耦合是一个常见的错误,尽管我有时也会犯这样的错误,而且你会在我的函数中看到全局/环境变量,但当我知道“这段代码不会发生太大变化”时就会发生这种情况。

哦,确保你不要$1直接使用或任何其他参数;总是使用local var_name="$1"

_USER_NAME="${USER_NAME:-"$USER"}"

# Bad - coupled
coupled_username(){
  echo "_USER_NAME = ${_USER_NAME}"
}

# Good - decoupled
decoupled_username(){
  local name="$1"
  echo "name = ${name}" 
}

# Usage
coupled_username  
decoupled_username "$_USER_NAME"
Enter fullscreen mode Exit fullscreen mode

函数式编程

本主题涉及函数和局部函数变量,其中函数尽可能“纯粹”。正如您在 中所见,除了初始化全局变量good_vibes.sh之外,几乎所有内容都包装在函数中

我不明白编写这个init_vars处理全局变量的函数有什么意义。不过,我发现自己validate_vars时不时会添加一个函数,用来遍历全局变量并验证它们的值。我相信这里面肯定有值得商榷的地方,所以欢迎大家发表你的看法。

最后的话

“Good Vibes 应用程序”主要介绍如何按照函数式编程范式编写可读的 Bash 脚本

如果你觉得有必要改变变量和函数的命名方式,那就去做吧!只要你的代码容易理解,你就走在正确的道路上。

本系列的下一篇博文将涵盖以下主题:

  • 错误处理
  • 从 HTTP 端点检索 JSON 数据
  • 使用fswatch在后台执行任务并监视文件变化
  • Git 存储库结构 - 将 Bash 脚本添加到现有存储库或使用 Bash CLI 应用程序创建新存储库
  • 将 Bash CLI 发布为Docker镜像

还有更多,更多……我会把所有想法都写进博文里。欢迎大家在评论区提出问题或建议,我会继续更新我的下一篇博文。

文章来源:https://dev.to/unfor19/writing-bash-scripts-like-a-pro-part-1-styling-guide-4bin
PREV
5+ 款 Python 游戏及源代码
NEXT
样式化组件 101 💅 讲座 2:创建主题 + 明暗主题切换器示例 ☀️🌙 创建主题文件 🔮 使主题文件可通过应用程序访问 🕵️ 在样式化组件中使用主题 💅 在自定义 React 组件中使用主题 ⚛️ 主题 prop 🤖 使用 JavaScript 对象编写样式而不是 CSS 🤹‍♀️ 现在... 👑 皇冠上的宝石:让我们使用样式化组件创建一个明暗主题切换器 结果 ☀️ ➡️ 🌙