记录下遇到的有趣的shell代码, 可能是一些常用的snippet, 也可能是使用的时候不经意踩到的坑
不定时更新
正确传递数组到函数中
1 | function update() { |
要特别注意的是,使用不当就造成只将数组的第一个数组到函数中
上面是正确的使用方法
使用sed修改Yaml文件中指定关键字的下N行
文件如下:
1 | this: |
现在要修改this所在行的下面2行
1 | sed -i "/this:/!b;n;n;c\ a: ${tmp_version}" ${file} |
- !b表示中断sed命令
- n表示读入下一行
- c表示将当前行修改为后面的字符串
因为a: a这行需要缩进2个空格,空格需要使用\
进行转义
查看进程占用的文件句柄
1 | # 用户级 |
使用sed删除多行内容
1 | env: prod |
对于上面的的yaml文件内容,如果想将sensebee3下的行直到http: 1234之间的内容都删除,但是sensebee3及http: 1234
这两行不删除,使用sed
如何操作呢?
1 | sed -i "/^sensebee3:/I,/^[^[:space:]#]/{//!d;}" file |
从上面的格式可以看出,只需要先确定范围,然后删除即可,
/^sensebee3:/
用于匹配sensebee3
/^[^[:space:]#]/
用于匹配到不是以空格及#
号开头的行,自然就匹配到了http: 1234
, 这样就选定了这两行之间的内容
{//!d;}
其中//
表示使用前面的正则表达式, !d
表示不删除, 这样就实现了sensebee3及http: 1234
这两行不会删除,只删除这两行之间的内容.
在脚本中修改crontab
1 | (crontab -l 2>/dev/null; echo '*/2 * * * * bash /usr/local/src/kestrel.openfiles.check > /usr/local/src/logs/kestrel_openfiles.check.$(date "+\%Y\%m\%d-\%H\%M\%S").details 2>&1') | crontab - |
善用{}
1 | ATEST="ISTEST" |
使用&&
||
有时为了shell命令能够简短, 经常会连着使用 &&(且) ||(或)
, 但是如果不多想一次的话,可能就会跟结果相背.
1 | 只有当command1成功(命令返回值为0), 才会执行command2 |
换行符
经常会有读取文件的需要, 用的最多的是使用for循环读取文件, 使用的时候需要特别注意文件的换行符, 默认情况下,换行符为空格, 需要使用IFS
指定为换行
1 | 测试文件 |
变量默认值
有时候定义变量的时候, 经常需要默认值, shell中也有一些比较有趣的表达式
1 | {value:=word} |
参数解析getops
在写脚本的时候,经常需要对参数进行解析,shell毕竟是个脚本语言, 不可能像python等高级语言一样有很完善的参数解析库, getops是bash自带的一个用于参数解析的工具, 但是它只是用于参数解析, 不能对参数进行更高级的操作,比如参数间依赖, 参数判断等
1 | function usage() { |
多if时不如使用case
在需要使用法if进行业务判断时, 不防使用case,相对于层层if, 代码会更加清晰
1 | if [[ "$lmode" == "master" ]]; then |
加载key-value类的配置文件
1 | cat xx |
一行代码: 字符串是否包含子串
1 | # 判断CONSUL_SERVER中是否包含逗号 如果包含EXPECT_LEN=3, 不包含EXPECT_LEN=1 |
for循环打印带空格字符串
1 | # 需求, 提供个数组,循环数组中的元素, 如果元素存在于某个文件中,则不追加,如果不存在,则追加 |