bash 实用技巧
- 将文件的内容赋给一个变量:
1.file=$(cat filelist)
2.file=$(< file)
NOTE:后者性能比前者好
- bash 分组匹配:
HOSTNAME='mysql-10=='
[root@node2 ~]# [[ $HOSTNAME =~ -([0-9]+)(.*) ]];VAR=${BASH_REMATCH[0]};echo $VAR
-10==
[root@node2 ~]# [[ $HOSTNAME =~ -([0-9]+)(.*) ]];VAR=${BASH_REMATCH[1]};echo $VAR
10
[root@node2 ~]# [[ $HOSTNAME =~ -([0-9]+)(.*) ]];VAR=${BASH_REMATCH[2]};echo $VAR
==
- 命令替换:
1.$(ls)
2.`ls`
- () 与 {}
1.新开一个子shell执行命令:
(umask 000;mkdir hello;mkdir word)
创建了两个目录,权限都为777
2.{ echo "hello"; }
note:两者之间的区别是,()是在产生的子shell下执行,而{}是在当前的shell下执行
- read
echo a b|(read a b;echo $b) #管道方式赋值给read
- set
set -x 以debug模式执行shell,显示执行过程
set -e 如果某一条shell出错就不再往后继续执行
set -u 如果引用了没有声明的变量则报错
通常在脚本中有两种写法:
1.set -eux
2.set -euo pipefail
set也可以在不执行脚本的时候设置位置参数
#!/bin/bash if [[ $@ ]] then echo $@ else set -- a fi echo $@
- eval
shell中不支持变量嵌套,将一个变量的值当成另外一个变量的变量名,这是后可以使用eval
#!/bin/bash name="ddddddddddddd" y="na" eval new=$(echo '$'"$y"me) echo ${new}
eval可读取一连串的参数,然后再依参数本身的特性来执行。eval命令将会首先扫描命令行进行所有的替换,然后再执行命令。该命令使用于那些一次扫描无法实现其功能的变量。该命令对变量进行两次扫描。这些需要进行两次扫描的变量有时候被称为复杂变量。
- 正则表达式:
[[space:]] #空白字符
[[:digit:]] #数字
[[:alnum;]] #数字和字母
[[:punct:]] #标点符号
[[:lower:]] #小写字母
[[:upper:]] #大写字母
[[:alpha:]] #大小写字母
. #匹配单个字符
* #匹配前面字符任意次
.* #匹配任意长度字符,也包含空行
\? #匹配前面字符一次或零次
\{m,n\} #匹配前面字符至少M次,最多n次
\(ab\) #分组匹配,主要用于搭配后项引用,前面匹配到什么,后面就引用什么(eg:grep "\(l..e\).*\1$" test #匹配以括号中匹配到的内容结尾的行)
位置锁定:
^ #行首(如果出现在'[ ]'中,则表示排除,eg grep '[^1-2]' test,表示排除除了1和2的行)
$ #行尾
^$ #空行
\< #词首
\> #词尾
- grep参数:
-i #忽略大小写
-n #显示行号
-c #统计符合条件的行
-v #排除符合条件的行
-An #打印符合条件行及下面的n行
-Bn #打印符合条件行及上面的n行
-Cn #打印符合条件的行及上下n行
egrep:
+ #匹配前面字符至少一次
? #匹配前面字符一次或零次
{m,n} #匹配前面字符至少m次,最多n次
(a|b) #匹配a或b
- sed:
参数:
-n 静默模式,不再显示模式空间的内容
-i 直接应用在文件中生效,如果不加-i,只是输出到屏幕而不应用到文件
-r 使用扩展正则表达式
-f 保存至文件执行
sed '/hello/a\test' test #在匹配到内容的下一行追加指定内容
sed 's/hello/&test/' test #在匹配到的内容后追加新内容
wd 's/hello/test&/' test #在匹配到的内容前追加新内容
sed '1i\test' passwd #在第一行前面添加test
sed '1a\test' passwd #在第一行后面添加test
sed -n '1'p passwd #打印第一行
sed '1w test' passwd #将第一行内容写到test中
sed '1r test' passwd #将test中的内容添加到第一行后面
sed 's/test/TEST/'g test #将test中的test换位大写的TEST
sed -i '/string/,+3d' . #删除匹配到的行及其下面的三行
sed -r -i 's/(version: [0-9].[0-9].)([0-9]+)/\1a/' Chart.yaml # sed 分组匹配
sed默认每次只替换一行中第一个命中的,如果要替换每行的所有匹配到的用[/g]:
sed -i 's/a/e/g' abcd.txt
如果只想替换每行第一次出现的,可以去掉[/g]:
sed -i 's/e/a/' abcd.txt
sed默认会匹配全文,也可以让他匹配指定次数就退出,可以用【0,/待替换内容/s/待替换内容/替换内容/】:
sed -i '0,/a/s/a/e/' abcd.txt
在第一次匹配的行做全部替换:
sed -i '0,/a/s/a/e/g' abcd.txt
如果每次想替换两行怎么办?那就把0,/改为1,只替换两行,替换两行中所有匹配到的/
sed -i '1,/a/s/a/e/g' abcd.txt
每次替换两行,每次替换每行中第一次匹配到的:
sed -i '1,/a/s/a/e/' abcd.txt
sed -i '0,/a/s/a/e/' abcd.txt #实现每次只替换一个a:使用【0,/待替换内容/s/待替换内容/替换内容/】
NOTE:
1.sed中/可以用@或者#代替
2.sed中如果要引用系统的环境变量,可以用单引号,如:sed '/`test`/d' test
3.从shell向sed传值: echo $NAME | sed "s/go/$REP/g" 注意需要使用双引号
eg:
sed 's#test#TEST#'g test
sed 's@test@TEST@'g test
替换字符位置:
#cat test
three one
sed 's/\(three\)\(.*\)\(one\)/\3\2\1/' test
res:
one three
- wait #保证进程同步 等待一个子进程结束:
#!/bin/bash echo “1” sleep 5& echo “3” echo “4” wait echo ”5”
- trap #是一个shell内建命令,它用来在脚本中指定信号如何处理:
trap "echo `date`" SIGINT #表示当前shell进程接收到CTRL+C信号时,打印出当前时间。
(参考博客:https://www.cnblogs.com/wjlv/p/10772888.html)
- script
shell 录屏:script -t 2> test.time -a test.txt
shell 回放(只会在屏幕播放,不会再执行)scriptreplay test.time test.txt
- multitail
多文件tail
multitail test.time test.txt #垂直窗口显示
multitail -s 2 test.time test.txt. #窗口并排显示
执行过程中按 b 键选择窗口
- exec
在 shell 中启动二进制的命令前加一个 exec 即可让该二进制启动的进程代替当前 shell 进程,即让新启动的进程成为主进程:
eg:
#!/bin/bash echo $$ exec sleep 60
- bash相关
: #占位符号
echo $((2**3)) #数值运算
((a=10+10));echo $a #数值运算
(pwd;ls) 与{pwd;ls} 的区别,{} 和()类似,也是将多个命令组合在一起。它们之间的区别是,()是在产生的子shell下执行,而{}是在当前的shell下执行
#####
until:给while 用法一致,不过while 是为真是循环,而until是条件为假时才执行
##########
shift:用于给脚本传多个关键字参数
while [[ $# -gt 0 ]]
do
#获取第一个参数
key="$1"
case $key in
#主节点IP
--master-address)
export MASTER_ADDRESS=$2
#向左移动位置一个参数位置
shift
;;
#获取docker存储路径
--docker-graph)
export DOCKER_GRAPH=$2
#向左移动位置一个参数位置
shift
;;
#获取docker加速器地址
--docker-mirrors)
export DOCKER_MIRRORS=$2
#向左移动位置一个参数位置
shift
;;
*)
# unknown option
echo "unkonw option [$key]"
;;
esac
shift
done
运行方式:kubeadm.sh --node-type master --master-address 10.40.72.51
##########
shell 数组:
ARR=(a b c)
#遍历数组:
for
NUM
in
${ARR[*]}
do
echo
$NUM
done
if echo "${ARR[@]}" | grep -w "a" &>/dev/null; then
continue
fi
#向数组添加新成员:
ARR[1]=
"item_1"
ARR[2]=
"item_2"
###echo 后面的内容加引号与不加引号的区别:
echo * #显示当前路径
echo "*" #显示*
- bash变量相关
ps1:修改默认提示符
ps2:修改分行符号 ##一个非常长的命令可以通过在末尾加“\”使其分行显示。多行命令的默认提示符是“>”。 我们可以通过修改PS2 ,将提示符修改为"continue->"
ps3:修改PS3——Shell脚本中使用select时的提示符
ps4:修改 set -x 脚本调试执行时前面显示的字符
参考连接:https://blog.csdn.net/rainharder/article/details/54573021
将二进制文件嵌入到shell脚本:
有时候我们的项目可以有二进制文件,有图片,有说明文档等,这个时候发布项目可以打成一个包或者一个文件夹有组织的存放这些文件,很方便,但有时候也可以把他们放入到一个shell脚本中,这个对用户也非常友好,只需要运行一个shell脚本就ok:
1.先写一个脚本:test.sh
#!/bin/bash
sed '1,5/d' $0 > test
echo "ok"
chmod +x test
exit 0
END
2.把二进制内容追加到test.sh 后面: cat 二进制文件 >> test.sh
嵌入后的shell:
#!/bin/bash
sed '1,5/d' $0 > test #将第一行至分隔符行删除,将后面二进制分离出来
echo "ok"
chmod +x test
exit 0
END ###分隔符
^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^B^@>^@^A^@^@^@`ÈF^@^@^@^@^@@^@^@^@^@^@^@^@p^B^@^@^@^@^@^@^@^@^@^@@^@8^@
原理:shell 运行时将对应的二进制分离出来然后执行。
生产环境shell字符处理实例:
#!/bin/bash dir="/home/feixiang.du/charts" all_project=`ls -l /home/feixiang.du/charts | sed '1,2d' | awk '{print $NF}'` for i in ${all_project} do #跳过指定charts ignore_chart=(istio istio-cni alert-hook istio-init nginx-demo auth demo phpserver-helloworld dove-override-svc-bj2 chartmuseum chartmuseum-external dove-override-svc-bj3 prometheus-operator pub-entry-nginx dove-override-svc-pub configmap-filebeat.yaml dove-server pub-entry-nginx-stream push-charts.sh rpcmon filebeat tech-sdkwrapper k8swan kubeapps log-clean log-collect inner-ingress crm-center-internal-api) if echo "${ignore_chart[@]}" | grep -w "$i" &>/dev/null; then continue fi if ! [ -f ${dir}/${i}/Chart.yaml ] then continue fi #处理charts版本 current_ver=`cat "${dir}/${i}/Chart.yaml" | grep "version" | awk -F. '{print \$NF}'` new_version=$(($current_ver+1)) sed -r -i 's/(version: [0-9].[0-9].)([0-9]+)/\1'$new_version'/' ${dir}/${i}/Chart.yaml #调整successThreshold = 2 sed -r -i '0,/successThreshold/s/(successThreshold: )([0-9])/\12/' ${dir}/${i}/templates/deployment.yaml #增加affinity if ! [ -f ${dir}/${i}/templates/deployment.yaml ] then continue fi ##删除charts中已存在的affinity行 sed -i '/affinity/,+3d' ${dir}/${i}/templates/deployment.yaml num=`cat -n ${dir}/${i}/templates/deployment.yaml | grep "Values.tolerations" |awk '{print $1}'` insert_num=$(($num-1)) sed -r -i ''$insert_num'r affinity' ${dir}/${i}/templates/deployment.yaml chartname=$i export chartname envsubst < values.tml > values sed -i '/affinity: {}/d' ${dir}/${i}/values.yaml sed -r -i '$r values' ${dir}/${i}/values.yaml done
posted on 2019-05-04 14:49 it_man_xiangge 阅读(426) 评论(0) 编辑 收藏 举报