热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

从如何编写幂等Bash脚本了解怎么实现幂等函数?·FatihArslan

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


当你你写了一个bash脚本,但是由于错误而运行一半退出了,当您修复了系统中的错误并再次运行这个脚本。但是脚本中的一半步骤会立即失败,因为它们已经作用于您的系统了。要构建弹性系统,您需要编写幂等的软件。(幂等在分布式环境同样重要,这样才能保证重试等正确实现)



什么是幂等?


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


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



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



Bash实现


让我展示一些bash技巧,可以用来改变你的脚本为幂等的。


1.创建一个空文件


这意味着您可以多次调用它而不会出现任何问题。第二次调用不会对文件内容产生任何影响。请注意,虽然它会更新文件的修改时间,但如果您依赖它,请小心。



touch example.txt


2.创建目录


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



mkdir -p mydir


3. 创建符号链接


通常做法:



ln -s source target


但是如果你再次在同一个目标上调用它,会失败。为了使其幂等,传递-f:



ln -sf source target


-f标志在创建符号链接之前删除目标符号,因此它将始终成功。


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



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


所以为了安全起见,请始终使用ln -sfn source target。


4.删除文件


传统:



rm example.txt


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



rm -f example.txt


5.修改文件


有时您正在向现有文件添加新的一行。如果再次运行这个脚本,则需要确保不要再次添加刚才添加的一行。假设你的脚本这样:



echo "/dev/sda1 /mnt/dev ext4 defaults 0 0" | sudo tee -a /etc/fstab


如果再次运行,您最终会有重复的条目/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语句。


(数据库操作同理)


6.检查变量,文件或目录是否存在


大多数情况下,您会写入目录,从文件读取或使用变量进行简单的字符串操作。例如,您可能有一个基于某些输入创建新文件的工具:



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:file并具有执行权限


假设您要安装二进制文件,但只有在主机中不存在二进制文件时,您才能使用-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并重新运行脚本,即可轻松将二进制文件升级到新版本。


7.格式化设备


要格式化卷,例如ext4格式化,一般使用如下命令:



mkfs.ext4 "$VOLUME_NAME"


如果再次调用它会立即失败。为了使这个调用是幂等的,我们在它前面添加blkid:



blkid "$VOLUME_NAME" || mkfs.ext4 "$VOLUME_NAME"


此命令打印给定块设备的属性。因此,预先基本上意味着仅在blkid失败时继续格式化,这表示给定的卷尚未格式化。


8.安装设备


尝试将卷装入现有目录:



mount -o discard,defaults,noatime "$VOLUME_NAME" "$DATA_DIR"


如果它已经安装,这将失败。一种方法是检查mount命令的输出并查看卷是否已经安装。但是有一种更好的方法可以做到这一点。使用mountpoint命令:



if ! mountpoint -q "$DATA_DIR"; then
mount -o discard,defaults,noatime
"$VOLUME_NAME" "$DATA_DIR"
fi



总结



从长远来看,创建幂等且有弹性的软件总是有益的。因此,了解它们是有用的。最近我在 bootstrap.sh
脚本中使用了上述所有提示和技巧 ,用于创建和配置我的 远程开发机器
。我知道我可以使用更复杂的工具从头开始配置VM,但有时候你需要一个简单的bash脚本。




推荐阅读
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 本文介绍了Linux Shell中括号和整数扩展的使用方法,包括命令组、命令替换、初始化数组以及算术表达式和逻辑判断的相关内容。括号中的命令将会在新开的子shell中顺序执行,括号中的变量不能被脚本余下的部分使用。命令替换可以用于将命令的标准输出作为另一个命令的输入。括号中的运算符和表达式符合C语言运算规则,可以用在整数扩展中进行算术计算和逻辑判断。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 解决.net项目中未注册“microsoft.ACE.oledb.12.0”提供程序的方法
    在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报错“未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序”。本文提供了解决这个问题的方法,包括错误描述和代码示例。通过注册提供程序和修改连接字符串,可以成功读取excel文件信息。 ... [详细]
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
author-avatar
Eosven_119
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有