shell脚本
Shell脚本 for循环 cat > a.sh <<EOF #!/bin/bash export NODE_NAMES=(kube-test1 kube-test2 kube-test3 kube-test4) for node_name in ${NODE_NAMES[*]} do echo ${node_name} done EOF sed 行上、行下操作 在匹配行下面插入一行文字 sed -i '/特定字符串/i 新行字符串' development.yaml 在匹配行下面插入一行文字 sed -i '/特定字符串/a 新行字符串' development.yaml 在匹配行下面插入一行文字 sed '/\/usr\/bin\/java/a /usr/local/jdk1.8.0_171/bin/java' /root/test.development.yaml 在匹配行下面插入一行文字 sed '/client/ a\default-character-set = utf8mb4' /etc/my.cnf 在首行插入一行文字 sed "1i #!/bin/bash" a.sh 在最后插入一行文字 sed -i '$a\要插入的文字' development.yaml 在第3行上面插入文字 sed '3i hello' /etc/passwd 在第3行下面插入一行文字 sed '2a\hello' a.txt 在第3行下面插入两行文字 sed '2a\hello\nhi' a.txt 在第3行下面插入文字 sed '3a hello' /etc/passwd 查找替换功能 普通查找替换 sed -i 's/原字符串/新字符串/g' development.yaml sed只对第三行查找替换 sed = /etc/passwd | sed 'N; s/\n/ /' | sed '3 s/d/c/g' sed只对第14行查找替换 sed -i '14 s/ens33/eth0/g' /etc/sysconfig/network-scripts/ifcfg-ens33 sed只对第55行查找替换成空格 sed -i '55 s/!//g' /etc/sudoers sed 替换特殊字符 / 把 /web/sing/ 替换成 /website/ sed -i 's/web\/sing/website/g' test1.conf #转义符放在斜杠的前面 sed行内整体替换 sed "2c jenkins=192.168.1.204" c.file sed带多个参数使用 sudo sed -i -n "17c Port 62000" /etc/ssh/sshd_config sed替换字符串内所有的空格 sed 's/ //g' 打印功能 打印第一行至第三行 sed -n '1,3p' development.yaml 打印第一行与最后一行 sed -n '1p;$p' development.yaml 删除功能 删除第二行 sed -i '2d' development.yaml 删除第一行至第三行 sed '1,3d' development.yaml 删除匹配行至最后一行 sed '/spec/,$d' development.yaml 删除最后6行 for i in `seq 1 6`; do sed -i '$d' development.yaml ; done 删除最后一行 sed '$d' development.yaml 删除偶数行 sed 'n;d' development.yaml 隔两行删除一行 sed 'n;n;d' development.yaml 删除匹配行 sed '/development/d' development.yaml 删除特定字符串的行 sed -i '/字符串/d' development.yaml 行内操作 查找name 并在其下添加namespace,a表示在其下一行添加文字 sed '/name/anamespace' development.yaml 查找name 并在其上添加namespace,i表示在其下一行添加文字 sed '/name/inamespace' development.yaml 查找以development为结尾的行,并在其行尾添加字符串word,$表示结尾标识符,&表示添加 sed 's/development$/&.v2/' development.yaml 查找以api开头的行,并在其行首添加nginx: sed -e '/api/s/^/&nginx:/' development.yaml 查找具有特定字符的行,把其中的某个字符进行替换 sed '/kind/s/Namespace/servece/g' development.yaml 查找具有特定字符的行,把行内所有文字进行替换 sed -i '/world/s/hello world/service/g' a.txt 多个sed命令 sed -e 's/development$/&.v2/' -e '/api/s/^/&nginx:/' development.yaml awk 打印硬盘设备名称,默认以空格分割 df -h | awk '{print $1}' 以冒号作为分割符 awk -F '[:]' '{print $1}' development.yaml 或者cat /etc/passwd | awk -F: '{print $NF}' 以空格作为分隔符 awk -F ' ' '{print $1}' development.yaml 或者awk '{print $1}' development.yaml 以制表符作为分隔符 awk -F '[\t]' '{print $1}' development.yaml 以分号作为分隔符 awk -F '[;]' '{print $1}' development.yaml 以冒号为分割,打印第一列,然后追加到/tmp/log awk -F: '{print $1>> "/tmp/awk.log"}' development.yaml 打印第三行到第五行,NR表示行 awk 'NR==3,NR==5 {print}' development.yaml 打印文件所有域 awk 'NR==3,NR==5 {print $0}' development.yaml 打印第三行到第五行的第一列和最后一列 awk -F: 'NR==3,NR==5 {print $1,$NF}' /etc/passwd 打印最后一列 cat /etc/passwd | awk -F ':' '{print $NF}' 或者 cat /etc/passwd | awk -F: '{print $NF}' 打印字符串长度大于10的行号 awk 'length($0)>10 {print NR}' development.yaml 引用shell变量,使用-v或者双引号+单引号 awk -v STR=hello '{print STR,$NF}' development.yaml 以冒号为分隔符,打印第一列同时打印前5行 awk -F: 'NR>=1 && NR<=5 {print $1}' development.yaml cat /etc/passwd | head -5 | awk -F: '{print $1}' development.yaml 打印第一列和所有行号 awk -F: '{print NR,$1}' development.yaml NR除以2等于0则跳过该行继续执行下一行,打印出来 awk -F: 'NR%2==0{next} {print NR,$1}' development.yaml awk分析nginx的日志状态码 404 503 等次数 统计次数大于20的 awk '{if ($9~/502|499|500|503|404/) print $1,$9}' access.log|sort|uniq –c|sort –nr | awk '{if($1>20) print $2}' awk统计服务器连接状态数 netstat -an | awk '/tcp/{s[$NF]++}END{for(i in s) print s[i] i}' netstat -an | awk '/tcp/{print $NF}' | sort | uniq grep grep -c "404" access.log 统计nginx日志中404的行数 grep -i "404" access.log 不区分大小写 查找404所在的行 grep -n "404" access.log 打印404的行以及行号 grep -v "404" access.log 不打印404所在的行 grep "api[Vv]" development.yaml 以字符api开头,接V或v 的行 grep "^[^api]" development.yaml 显示输出不是api的行 grep "[Aa]p" development.yaml 匹配 A或a开头,后接p的行 grep -c "name" development.yaml 统计name出现的次数 grep -i "name" development.yaml 不区分大小写,查找name所在的行 grep -n "name" development.yaml 打印name所在的行和行号 grep -v "name" development.yaml 不打印name所在的行 grep "api[Vv]" development.yaml 查找以api开头的,后接V或v的行 grep "^[^api]" development.yaml 显示出行首不是api的行 grep "[Aa]pi" development.yaml 匹配A或a开头的行 grep "[a...e]" development.yaml 匹配a,三个任意字符,紧接e的行 grep "[a-z][p]i" development.yaml 匹配小写字母,紧接pi的行 cut 在 /etc/passwd 中输出第 3-5 列:cat /etc/passwd | cut -d ':' -f 3-5 在 /etc/passwd 中输出第 3到最后一列:cat /etc/passwd | cut -d ':' -f 3- shell数组 数组定义 一对括号表示是数组,数组元素用“空格”符号分割开。 a=(1 2 3 4 5) 数组读取与赋值 得到长度: [chengmo@centos5 ~]$ echo ${#a[@]} 5 用${#数组名[@或*]} 可以得到数组长度 读取: [chengmo@centos5 ~]$ echo ${a[2]} 3 [chengmo@centos5 ~]$ echo ${a[*]} 1 2 3 4 5 用${数组名[下标]} 下标是从0开始 下标是:*或者@ 得到整个数组内容 赋值: [chengmo@centos5 ~]$ a[1]=100 [chengmo@centos5 ~]$ echo ${a[*]} 1 100 3 4 5 [chengmo@centos5 ~]$ a[5]=100 [chengmo@centos5 ~]$ echo ${a[*]} 1 100 3 4 5 100 直接通过 数组名[下标] 就可以对其进行引用赋值,如果下标不存在,自动添加新一个数组元素 删除: [chengmo@centos5 ~]$ a=(1 2 3 4 5) [chengmo@centos5 ~]$ unset a [chengmo@centos5 ~]$ echo ${a[*]} [chengmo@centos5 ~]$ a=(1 2 3 4 5) [chengmo@centos5 ~]$ unset a[1] [chengmo@centos5 ~]$ echo ${a[*]} 1 3 4 5 [chengmo@centos5 ~]$ echo ${#a[*]} 4 直接通过:unset 数组[下标] 可以清除相应的元素,不带下标,清除整个数据 特殊使用 分片: [chengmo@centos5 ~]$ a=(1 2 3 4 5) [chengmo@centos5 ~]$ echo ${a[@]:0:3} 1 2 3 [chengmo@centos5 ~]$ echo ${a[@]:1:4} 2 3 4 5 [chengmo@centos5 ~]$ c=(${a[@]:1:4}) [chengmo@centos5 ~]$ echo ${#c[@]} 4 [chengmo@centos5 ~]$ echo ${c[*]} 2 3 4 5 直接通过 ${数组名[@或*]:起始位置:长度} 切片原先数组,返回是字符串,中间用“空格”分开,因此如果加上”()”,将得到切片数组,上面例子:c 就是一个新数据。 替换: [chengmo@centos5 ~]$ a=(1 2 3 4 5) [chengmo@centos5 ~]$ echo ${a[@]/3/100} 1 2 100 4 5 [chengmo@centos5 ~]$ echo ${a[@]} 1 2 3 4 5 [chengmo@centos5 ~]$ a=(${a[@]/3/100}) [chengmo@centos5 ~]$ echo ${a[@]} 1 2 100 4 5 shell数组编程 数组是相同数据类型的元素安一定顺序排列的组合,就是把有限个类型相同的变量用一个名字引用,然后用编号区分它们变量的集合 创建和定义数组 TEST=(test1 test2 test3) 数组下标一般从0开始,引用数组方法如下 echo ${TEST[0]} 引用第一个数组变量 echo ${TEST[1]} 引用第二个数组变量 echo ${TEST[@]} 显示该数组所有参数 echo ${#TEST[@]} 显示该数组参数个数 echo ${#TEST[0]} 显示test1字符长度 echo ${TEST[@]:0} 打印数组所有值 echo ${TEST[@]:1} 打印从第二值个开始的所有值 echo ${TEST[@]:0:2} 打印第一个值和第二个值 echo ${TEST[@]:1:2} 打印第二个值和第三个值 数组删除 unset array[0] 遍历数组 cat > a.sh <<EOF #!/bin/bash export NODE_NAMES=(kube-test1 kube-test2 kube-test3 kube-test4) for node_name in ${NODE_NAMES[*]} do echo ${node_name} done EOF 脚本实例: shell脚本安装python、pip 首先把pip-18.0.tar.gz 、Python-3.6.5.tgz 安装包放在 /usr/local 下面,按照顺序先安装pip,再安装python。不要先安装或只安装python,否则很容易出错, [root@bogon ~]# cat pip-python.sh #!/bin/bash func1(){ #安装依赖包 yum -y groupinstall "Development tools" [ $? -eq 0 ] && yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel } func2(){ #安装pip yum remove pip -y && cd /usr/local/ && tar -xf pip-18.0.tar.gz && cd pip-18.0/ && python setup.py install [ $? -eq 0 ] && echo "安装完成pip" } func3(){ #安装python cd /usr/local/ && tar -zxvf Python-3.6.5.tgz && mv Python-3.6.5 python3 && cd python3 && ./configure && make && make install [ $? -eq 0 ] && mv /usr/bin/python /usr/bin/python.bak [ $? -eq 0 ] && ln -s /usr/local/bin/python3 /usr/bin/python && ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3 [ $? -eq 0 ] && whereis pip && /usr/local/bin/pip3.6 install --upgrade pip && /usr/local/bin/pip install paramiko [ $? -eq 0 ] && sed -i "1c #!/usr/bin/python2.7" /usr/bin/yum [ $? -eq 0 ] && sed -i "1c #!/usr/bin/python2.7" /usr/libexec/urlgrabber-ext-down [ $? -eq 0 ] && sed -i "1c #!/usr/bin/python2.7" /usr/sbin/firewalld [ $? -eq 0 ] && sed -i "1c #!/usr/bin/python2.7" /usr/sbin/firewalld [ $? -eq 0 ] && echo "安装完成python" } #脚本菜单函数 menu(){ clear echo "# 1. 安装依赖包" echo "# 2. 安装pip" echo "# 3. 安装python" echo "# 4. 退出程序" } #功能选择函数 choice(){ read -p "Please choice a menu[1 2 3 4]:" select } #程序开始 while true do menu choice case $select in 1) func1;; 2) func2;; 3) func3;; 4) exit;; *) echo "choice error" esac done