新手入门?这里有一些建议
当我开始使用 Bash 编写脚本时,我一开始完全无法理解。我当时还比较年轻,困惑的原因可能就在于此。当时我使用的是 Python,感觉每次我想做某件事,都需要一些特殊的符号或咒语才能实现。Bash 功能强大,而且非常宽容,正因为如此,用它做一些愚蠢的事情非常容易。
需要明确的是,这篇博文更多的是关于 bash 中的良好约定,而不是它的语法或如何使用它做基本的事情。
这是启动 bash 脚本的方法
我本来想讨论一下内置命令 set ,但我意识到这不是启动 bash 脚本的方法。方法如下:
#!/usr/bin/env bash
这被称为shebang。通过将其作为第一行,您可以确保使用默认 bash 运行,这是$PATH
环境变量中对它的第一次引用。这是一种快捷方式,但是一个很好的惯例。(除非出于安全考虑,您担心有人会篡改您的$PATH
环境变量。)
现在说真的。这是启动 Bash 脚本的方法
#!/usr/bin/env bash
set -euo pipefail
set内置命令是 Bash 工具包中一个相当复杂且实用的元素。为了说明我的观点,我会稍微简化一下,但这里还是给出一个解释:set允许你配置Bash在某些关键场景下的行为。
让我们简单介绍一下:
set -e
此选项将导致 bash 脚本在命令失败时立即退出。这通常比默认行为有了很大的改进,默认行为是脚本直接忽略失败的命令并继续执行下一行。set -u
导致 bash shell 将未设置的变量视为错误并立即退出。set -o pipefail
将管道的退出代码设置为最右侧命令的退出代码,以便以非零状态退出;如果管道中的所有命令都成功退出,则设置为零。实际上,set -e
如果没有此选项,则设置本身就毫无意义,因为如果命令管道在中间某处发生严重故障,它将不会退出脚本。
好吧,我做了设置,这让我很头疼。该怎么办?
很确定你最终会因为set -euo pipefail
这样或那样的原因遇到麻烦。例如,你可能决定提供一些可选的参数,然后set -u
就会惹上麻烦。这时你会这样做:
if [[ -z "${oxygen:-}" ]]; then
echo "Huston we have a problem!"
fi
此条件检查给定参数是否oxygen
未设置(或为空字符串)。重点在于:-
表达式。如果没有表达式,set -u
脚本将失败,因为它将无法进行参数扩展。使用:-
表达式将保持未设置状态,我们将传递错误。顺便说一下,这是添加默认参数的方法。:-
如果参数未设置,则后面的内容将用作默认值。如下所示:"${oxigen:-nitrogen}"
另一个常见问题是,当你预期某些操作会失败,或者你想明确地处理它时。set -eo pipefail
如果任何操作以非零的退出状态退出,Naturally 就会退出你的脚本。要处理这种情况,你可以使用#pipepipetrue:
echo 'Here comes the rough part'
my_fate=$("${dark_cellar}"/russian_roulette.py --load "${bullet}" || :)
echo 'Keep going, whatever'
该表达式|| :
将抹去您的错误并让您的脚本运行。
我可以做点什么。但我做得对吗?
正如我们所说,在 Bash 中有很多方法可以实现某些功能。幸运的是,在线社区非常棒,很容易找到能满足你需求的单行代码。但这真的安全吗?我学到了一件事:总有一些你没有想到的情况。
如果你有一位 Linux 专家朋友,能帮你找出所有错误,那就太好了。但即使你没有这样的朋友,你仍然可以拥有一个优秀的静态分析器!
认识shellcheck。
如果您使用 bash,也请使用 shellcheck。它会警告您有关错误和常见的不良做法,这些做法可能会导致无法预见的后果。设置起来很简单,只需使用 apt 命令即可:
sudo apt update
sudo apt-get install shellcheck
您可以简单地对任何脚本运行它,shellcheck myscript.sh
它就会为您提供指导!
宽容并不意味着你不应该模块化
如果你在公司做过 DevOps 工作,你可能会注意到每个 Bash 脚本基本上都是按顺序排列的操作列表。不像 Python 脚本,社区实践会鼓励你创建函数,并确保遵循单一职责原则。但谁说你不能在 Bash 中做同样的事情呢?参见:
function get_to_the_choppa() {
local mate=$1
echo "${mate}! Get to the choppa!"
}
get_to_the_choppa "Jack"
通常情况下,如果你不知道 bash 的行为方式,在某些情况下它会欺骗你,所以让我们看看最常见的情况:
- 使用
local
变量。函数中声明的所有内容都可以在函数作用域之外使用。为了避免这种情况,必须显式地将变量声明为局部变量。 - 选择一种约定并保持一致。你可以用多种方式声明一个函数。确保只使用一种。
function take_pills() {
echo "Get better"
}
function dink_tea {
echo "Get better"
}
rest_in_bed() {
echo "Get better"
}
- 你可以用 return
echo
。Bash 有一个return
语句,但你只能用它来指定函数的退出状态。要从函数中获取值,解决方案可以是在函数中设置全局变量,而不使用 local 关键字,但最好还是明确一点!你只需捕获函数回显的内容即可。
function interrogate() {
echo "It was Hank!"
}
who_to_blame=$(interrogate)
了解 Linux
如果您是 Bash 新手,那么 Linux 对您来说肯定也是陌生的。我并非最能讲解所有 Linux 基础知识的人,但我可以分享一个很棒的免费资源,我刚开始学习 Linux 时也用过。如果您还有什么不明白的地方,可以访问linuxjourney
阅读。它对每个基本概念和高级概念都进行了简单易懂的描述,并且拥有赏心悦目的简洁用户界面。 这个页面简洁明了,甚至能教猴子使用 Linux。一定要去看看!
最后,两条建议
听听我的两条建议,当事情不如预期时就应用它们。当时我觉得这些步骤非常重要,所以我把它们写在便签上,贴在显示器底部。它们如下:
第一步:再次阅读该代码。
是不是哪里出了问题?别慌。我会告诉你会发生什么:过一段时间,你就会发现自己犯的错误,甚至可能就在你眼前。你可能觉得一切都没问题,但你使用的某些组件存在冲突?那就直接跳到第二步吧。
第二步:几乎总是你。
您可能会认为某些组件不兼容,或者您使用的版本不支持某些用例。但通常并非如此。通常是您自己搞砸了。回到第一步。
鏂囩珷鏉ユ簮锛�https://dev.to/pencillr/newbie-at-bash-scripting-heres-some-advice-j1a