Welcome to

快雪Tang

Home / devops

Bash Tricks: string

Bash 字符串操作极其强大,尽管还无法和高级语言的能力相比肩,但在bash中你已经几乎可以完全操纵任何文本、任何字符串了。   字符串操作和变量有密切关联性,所以先介绍变量及其表达式的使用惯例: ${var} 变量var的值, 与$var相同 ${var-DEFAULT} 如果var没有被声明, 那么就以$DEFAULT作为其值;否则其值为 $var ${var:-DEFAULT} 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值;否则其值为 $var ${var=DEFAULT} 如果var没有被声明, 那么就以$DEFAULT作为其值;否则其值为 $var ${var:=DEFAULT} 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值;否则其值为 $var ${var+OTHER} 如果var声明了, 那么其值就是$OTHER;否则就为null字符串 ${var:+OTHER} 如果var被设置了, 那么其值就是$OTHER;否则就为null字符串 ${var?ERR_MSG} 如果var没被声明, 那么就打印$ERR_MSG;否则其值为 $var ${var:?ERR_MSG} 如果var没被设置, 那么就打印$ERR_MSG;否则其值为 $var ${!varprefix*} […]

Read More

bash tricks: no alias, in source, …

BASH: \ls 前缀\的目的是避免alias替换,使用命令的原生目标来执行。当 alias ls=’ls –color’ 时,ls的输出结果是带高亮色的,\ls则避免了alias替换,输出结果没有高亮色。   BASH:函数名 function test_func() { echo “Current $FUNCNAME, \$FUNCNAME => (${FUNCNAME[@]})” another_func echo “Current $FUNCNAME, \$FUNCNAME => (${FUNCNAME[@]})” } $FUNCNAME是一个数组,包含倒序的函数名调用栈。例如“(child_func parent_func main_entry main)”,其中main_entry是首个函数调用入口,然后依次嵌套调用函数 parent_func 和 child_func,而main是一个伪函数名,它表示整个脚本文件。   BASH:避免多次source BASH自身检测SOURCE状态 使用一个环境变量来标识已经source过了 _sourced_=”__sourced_$$__” echo “Flag […]

Read More

bash rename,批量重命名就靠它了

bash中重命名文件一般是使用内置命令mv来完成的。mv的本质含义是移动一个文件,在bash中使用它则无须在文件系统中查找命令文件。 然而mv的语法受到很多限制,如果你需要重命名一批文件的话,它就不合适了。 幸运的是还有 rename 这条命令,而且在绝大多数 linux 发行版中,rename都是存在的并且表现一致。 rename 批量重命名可以使用 rename 命令,这个命令允许你使用正则式完成一堆文件名的策略性重命名操作。 rename的语法如下: Usage: rename [ -h|-m|-V ] [ -v ] [ -n ] [ -f ] [ -e|-E *perlexpr*]*|*perlexpr* [ *files* ] Options: -v, -verbose Verbose: print names of files […]

Read More

ops-toolset history 1

几年前在公司开发了一整套运维服务器脚本工具集,命名为 xxx OPS Toolset。 记得当年更迭了N多个版本之后,才最终成型,因为bash的编程能力在结构化组织上还是有限的,所以那时候也是下了功夫的。 现在公司的服务器群全部迁离了阿里云,这套工具集也顺应变化更新了若干次,最主要的变化是现在更通用了,不限于哪个公有云,几乎都能自适应。当然,新的版本乃至旧的版本目前还不能放出来;不过旧版本的截图,昨夜整理时发现,倒是可以post出来,也是对几年前工作的一个小小的回顾吧。 至于说框架结构,实际上我还是整理了两套的,分别是: bash-framework: https://github.com/hedzr/bash-framework bash.sh: https://github.com/hedzr/bash.sh bash-framwork 呢,基本上是 ops toolset 的框架结构,也可以说是一个最小集合的Bash脚本编程框架,主要面向 DevOps 管理任务。 因此,默认的函数集合中包含了像 package-install, is_package_installed, if_ubuntu, if_centos, is_root 这类辅助函数。 不过,由于安装主站的vps不稳定,所以它的分发大约是有问题的,需要的朋友自己去拉源码再自行改造适用了。 至于 bash.sh 就微型得多了。 bash.sh主要是面向单文件开发。bash-framwork主要是面向整套脚本集合的组织、开发,适合组织成系列的大型脚本集合。反过来说 bash.sh 则是一个快速的起点,例如你需要在建设rabbitmq集群方面做一套子命令集合,那就可以直接clone bash.sh的主文件改成 rmq-ctl,然后直接编写bash函数到这个文件中,就可以使用像 rmq-ctl init 3 nodes 这样的命令了。所以像 sdkman 那样的命令套装,用 bash.sh 可以很容易实现。 […]

Read More

运维账户免密sudo

因为背不住,也不想转到脚本那边去check源码,所以快速笔记一下: groupadd -g222 devops groupadd -g225 admin groupadd -g333 hzadmin cat >/etc/sudoers.d/hzadmin<<EEE %devops  ALL=(ALL) NOPASSWD:ALL %hzadmin  ALL=(ALL) NOPASSWD:ALL %admin  ALL=(root) NOPASSWD: /bin/systemctl EEE usermod -aG hzadmin,devops me sudo 命令免密的关键,在于 NOPASSWD:ALL。如果想要给特定账户而不是账户组授予特定权限,则可以用: someone ALL=(root) NOPASSWD: /bin/systemctl 这个示例可以给账户someone授予执行systemctl的权利。类似的journalctl也可以这么做。 不过,也可以选择将账户加入到某个特定组,例如adm组、或者www-data组,的方式来使其具有特别权利。      

Read More

Vagrant 扩容虚拟机硬盘

这是个老问题,而且也并不限于Vagrant box环境,实际上对于Virtualbox环境来讲是通用的。 针对Vagrant – Ubuntu 环境 最简单的办法适用于Ubuntu虚拟机。Virtualbox – Ubuntu虚拟环境在这方面最为省心。下面用Vagrant box的序列来讲解如果超简便地随心所欲扩容。 假定你已经创建了Vagrant下的Ubuntu虚拟机实例: vagrant init ubuntu/xenial vagrant up vagrant ssh 当虚拟机启动时,你会查看到ubuntu的box所带来的是一个10GB的系统盘,现在我们要扩容它到40GB,首先还是进到Vagrantfile所在的目录用 vagrant halt 关机,然后在virtualbox app的界面中选中对应的虚拟机,进入设置-存储页面,找到vmdk磁盘镜像文件所在的位置,然后用命令行进入那个文件夹,例如:`$HOME/VirtualBox VMs/demovm_osdd_1496389870606_49381/ubuntu-xenial-16.04-cloudimg.vdi` ,现在我们开始调整镜像文件: VBoxManage clonehd ubuntu-xenial-16.04-cloudimg.vmdk ubuntu-xenial-16.04-cloudimg.vdi -format VDI VBoxManage modifyhd ubuntu-xenial-16.04-cloudimg.vdi –resize 40000 现在我们建立了一个原镜像文件的副本,但是是vdi格式,并且调整了镜像的尺寸,整个过程耗时不多,非常有效。 下面就是在virtualbox中该虚拟机的设置-存储页面中,用新的vdi副本替换vmdk的镜像文件就行了。 然后就可以vagrant up && […]

Read More

今天发了一个consul tags工具

缘由 因为consul都已经0.8.0了,还是没有动态修改tags的功能(这是一个老生常谈的问题了,不过consul很坚持,哪怕PR都已经做好了,只等着动动拇指了,也还是不行)参见修订,通过api去做的话,又会超级繁琐和比较没办法,所以做了一个工具去处理tags的添加、删除;进一步的,提供一个翻转的功能。 consul service能够带有一组tags,consul的编程接口和API都能够通过tags来筛选services,因此我们通常会将一个服务的实例集群的角色也提供在tags中,例如 role=master,type=disk,rw=readwrite,等等。这时候 LoadBalancer 就能够通过筛选tags来获得可用列表。 例如向 redis 服务发出 rw=readwrite 筛选条件后得到的可用实例表经过 LoadBalancer 处理后对业务层可用,这样业务层就可以写入键值;反过来筛选 rw=readonly 得到的实例表,业务层就可以读取键值,通过 LoadBalancer 附着一个 ReadWriteSpliiter 的架构设计,业务层实质上可以透明地获得负载均衡后的 redis 服务,并且该服务内部隐含地完成了读写分离的 devops 架构。 类似的,DB也可以采用这样的设计方案。 话说回来,也不必鄙视consul坚决不提供tags修改功能或者在service definition中附着一个子K/V,两者各有各的问题,而集中使用单一一个全局的K/V事实上也是相当正确的做法。然而不符合直觉啊,为什么大家总是要想reload一个新tag,而不愿意使用K/V呢,甚至愿意放弃分布锁也要改tag?这是个很严肃的问题。 key+问题 无论如何,回到我们描述的那种策略中,那么这里就存在一个问题了,consul很难动态修改tags,这样的架构设计就难以落地了。 consul确实准许重新注册相同id的实例并能够在这个场景中正确的设置到新tags集合。但那是针对string,而不是key=value。 这时要简单地把key-value应用进去就不那么便利了。不过还是可以有方法。 一种方法是对该设计进行一点点微调,采用 consul 的 KV Store 来保存服务实例的角色,并在高可用切换场景下更新该key。 这个方法成本低廉,而且实际上利用ZooKeeper,Etcd来做服务发现的案子,谁又不是这么做的呢?所谓的成本低廉,是因为 consul v0.6+ […]

Read More

Foreman 的 AWS EC2 Provider 在 AWSCN 中无法工作的问题

foreman 中使用的是 fog-aws 0.13.x 来完成AWS管理。 通过 Foreman-ec2 你可以将AWS EC2定义为一个计算资源(Compute Resource),随即用于创建新的EC2实例,这一切很流畅,如果你使用AWS International的话。然而如果使用AWS CN(http://www.amazonaws.com.cn/),当你安装了foreman-ec2插件之后,试图新增计算资源的话,fog-aws的这个早期版本只会在非AWSCN中试图验证你的AWSCN Token,结果当然是悲剧的:“ AWS was not able to validate the provided access credentials ”。 fog-aws的新版本已经解决了这个问题。然而更新foreman捆绑的版本不是真的好主意。

Read More

Ubuntu 14.0.4/Mac 安装nodejs开发或生产环境 (rvm)

首先来讲,Mac上可以有几种安装nodejs开发环境的方法,然而各种坑我都踩过了,还是建议rvm来安装nodejs,事实上好像我现在并没有遇到什么古怪的问题了,所以这篇文章其实并不能解决初学者的所有问题,顶多只是把一种最佳流程给记录下来罢了。 首先还是上脚本,适用于Ubuntu,Bash环境,同时也适用于Mac的Terminal/iTerm2环境(但需要一点点更改,主要是去掉apt-get相关的指令):

Read More