3

如何编写幂等的 Bash 脚本?- Arslan

 2 years ago
source link: https://www.jdon.com/57933
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

如何编写幂等的 Bash 脚本?- Arslan

您编写了一个 bash 脚本,但由于错误而中途退出,您修复系统中的错误并再次运行脚本。但是脚本中的一半步骤会立即失败,因为它们已经应用于您的系统。要构建弹性系统,您需要编写幂等的软件。

什么是幂等性?

幂等脚本可以被多次调用,每次调用都会对系统产生相同的影响。这意味着,第二次调用将以相同的结果退出并且不会产生任何副作用:

幂等的:表示集合中的一个元素在与自身相乘或以其他方式操作时其值不变。

好的软件总是以幂等的方式编写的,尤其是当您在分布式系统中工作时,其中的操作可能最终是一致的,并且您可能会因重复请求(例如在具有At-Least-Once交付保证的队列中)而多次调用函数。

让我展示一些 bash 技巧和习惯用法,您可以使用它们将脚本更改为幂等的。您可能正在使用其中的大部分,而没有意识到副作用:

创建一个空文件

这是个简单的。默认情况下,touch是幂等的。这意味着您可以多次调用它而不会出现任何问题。第二次调用不会对文件内容产生任何影响。请注意,它会更新文件的修改时间,因此如果您依赖它,请小心。

touch example.txt

创建目录

切勿mkdir直接使用,而是与-p标志一起使用。如果目录存在,此标志确保 mkdir 不会出错:

mkdir -p mydir

创建符号链接

如果你在同一个目标上再次调用它,这将失败。要使其具有幂等性,请传递-f标志:

ln -sf source target

-f标志在创建符号链接之前删除目标目的地,因此它总是会成功。

链接目录时,您也需要传递-n。否则再次调用它会在目录中创建一个符号链接。

mkdir a
ln -sf a b
ln -sf a b
ls a
a

因此,为了安全起见,请始终使用ln -sfn source target.

删除文件

使用-f 忽略不存在文件的标志。

rm -f example.txt

有时您会在现有文件中添加新行(即:)/etc/fstab。这意味着,如果您运行脚本,您需要确保不会第二次添加它。

幂等的一种方法是确保通过以下方式检查grep某些占位符:

if ! grep -qF "/mnt/dev" /etc/fstab; then
  echo "/dev/sda1 /mnt/dev ext4 defaults 0 0" | sudo tee -a /etc/fstab
fi

这里的-q意思是静默模式和-F启用fixed string模式。如果/mnt/dev不存在,Grep 将无声地失败,因此永远不会调用 echo 语句。

检查变量、文件或目录是否存在

大多数情况下,您正在写入目录、读取文件或使用变量进行简单的字符串操作。

。例如,您可能有一个基于某些输入创建新文件的工具:

echo "complex set of rules" > /etc/conf/foo.txt

计算文本可能是一项昂贵的操作,因此您不想每次调用脚本时都编写它。为了使其具有幂等性,您可以通过shell的-f的内置test属性的标志检查文件是否存在:

if [ ! -f "/etc/conf/foo.txt" ]; then
 echo "complex set of rules" > /etc/conf/foo.txt
fi

-f只是一个示例,您可以使用许多其他标志,例如:

  • -d: 目录
  • -z: 零长度的字符串
  • -p: 管道
  • -x: 文件并具有执行权限

假设你想安装一个二进制文件,但只有当它不存在于你的主机中时,你可以使用-x这样的:

# install 1password CLI
if ! [ -x "$(command -v op)" ]; then
  export OP_VERSION="v0.5.6-003"
  curl -sS -o 1password.zip https://cache.agilebits.com/dist/1P/op/pkg/${OP_VERSION}/op_linux_amd64_${OP_VERSION}.zip
  unzip 1password.zip op -d /usr/local/bin
  rm -f 1password.zip
fi

这会将op二进制文件安装到 /usr/local/bin。如果您重新运行脚本,它将不再安装它。另一个好处是,您只需将二进制文件从系统中删除,更新OP_VERSION env 并重新运行脚本,即可轻松将其升级到新版本。

有关完整标志和运算符的列表,请查看 man test。

我最近在bootstrap.sh 用于创建和配置远程开发机器的脚本中使用了上述所有提示和技巧 。我知道我可以使用更复杂的工具从头开始配置 VM,但有时一个简单的 bash 脚本是您唯一需要的东西。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK