美文网首页
bash语言笔记

bash语言笔记

作者: DayBreakL | 来源:发表于2019-08-06 00:41 被阅读0次

    测试开发的shell水平

    • linux

      • 文件操作
      • 网络操作 netstat
      • 系统数据分析 ps、top
      • 数据分析能力(linux 三剑客)
    • shell语法、脚本、管道、环境变量

    • 编写各种自动化脚本

      • 环境部署自动化
      • 测试用例调度自动化
      • jenkins持续集成中辅助脚本

    bash语言总览

    • 变量

    • 逻辑控制

    • shell环境

    • 脚本应用

    • 自动化

    变量

    变量的定义

    a=1
    b=daybreak
    c="hello world"
    d='你玩过"吃鸡"游戏吗'
    e=`pwd`
    
    • =左右两边不要有空格
    • 双引号支持转义
    • $ 开头的变量会被自动替换

    变量的使用

    echo $a
    echo ${b}
    echo "${a}"
    
    • 使用$var${var}来访问变量。后者更严谨。$var_x${var_x}是不同的
    • 变量未定义也可以使用。引用未定义的变量 ,默认为空值

    预定义变量

    echo $PWD
    echo $USER
    echo $HOME
    echo $PATH
    

    数组变量

    • 定义数组变量
    array=(1,2,3)
    array=(`ls`)
    
    • 使用数组变量
    echo ${array[index]}
    echo ${array[*]}  //获取数组中的所有元素
    echo ${#array[*]} //获取数组的长度
    

    变量类型

    • 字符串 a="hello"
    • 数字 b=1
    • 布尔 c=true

    数字型变量操作

    • 计算
    i=1;
    echo $i
    echo $(i+1)
    
    • 更新
    i=i+1;
    echo $i
    
    • 注意
      • 只能进行整数运算
      • 浮点数计算请使用awk 'BEGIN{print 1/3}'
      • 格式化显示可以换用 awk'BEGIN{print("%.2f\n,1/3")}'

    字符串操作

    • 取值
      ${string:start:lenght} 从变量中提取字串

      a="hello"
      echo ${a:0:3}   #结果为hel
      

      ${#string} 获取字符串长度

    • 掐头去尾与内容替换
      ${string#pattern} ${string##pattern} #表示掐头
      ${string%pattern} ${string%%pattern} %表示去尾
      ${string/pattern/替换的string} ${string//pattern/替换的string} /表示替换
      使用#或##、%或%%、/或//的区别:最短匹配或最长匹配模式

    布尔变量

    • true
    • false
    • 命令执行返回值$?
    命令
    echo $?
    
    #任何命令执行都有一个返回值,0表示正确,非0表示错误
    

    判断类型

    • 算术判断
      -eq 等于 [2 -eq 2]
      -ne 不等于
      -gt 大于
      -ge 大于等于
      -lt 小于
      -le 小于等于

    • 字符串判断
      [string1=string2] 两字符串相同,则结果为真
      [string1!=string2] 两字符串不相同,则结果为真
      [-n "$var" ] 如字符串不是空,则结果为真
      [-z "$var" ] 如字符串是空,则结果为真
      [["xxxx"==x*] ] 在表达式中表示0或者多个字符
      [[xxx==x??]] 在表达式中表示单个字符

      • 在引用变量的时候要记得加双引号[-z "$var" ]否则当a未定义时会语法报错
    • 逻辑判断
      [2 -ge 1 -a 3 -ge 4];echo $? -a and 与
      [2 -ge 1 -o 3 -ge 4];echo $? -o or 或
      [2 -ge 1 && 3 -ge 4];echo $?
      [2 -ge 1 || 3 -ge 4];echo $?
      [!2 -ge 1 ];echo $?

    • shell内置判断
      -e file 如果文件存在,则结果为真
      -d file 如果文件是一个子目录,则结果为真
      -f file 如果文件是一个普通文件,则结果为真
      -r file 如果文件可读,则结果为真
      -s file 如果文件的长度不为0,则结果为真
      -w file 如果文件可写,则结果为真
      -x file 如果文件可执行,则结果为真

      • [[]][]的拓展语法,在老的sh里并不支持。推荐用[]

    逻辑控制

    If结构

    • if [condition];then...;fi

    • if [condition];then...;else...;fi

    • if [condition];then...;elif...;fi

    • 简单的逻辑可以使用&& ||去替代

    • 条件可以用命令返回值代替

    for 循环

    • 语法
    for((i=0;i<10;i++));do echo $i;done
    
    • for遍历循环
      用于递归数组和递归以空格隔开的字符串,或者某个命令的返回值
      for f in $array[*];
      do
      ...;
      done
      
      ss="aa bb cc dd";for x in $ss;do echo $x;done
      for x in `ls`;do echo $x;done
      ss=(aa bb cc "sss dd");for x in "${ss[@]}";do echo $x;done
      

    while循环

    • 语法
    i=0;
    while [$i -lt 3];
    do echo $i;
    ((i=i+1));
    done
    
    • 一行行读取文件
    while read line;
    do echo $line;
    done<tmp/tmp
    

    退出控制

    • return 函数返回
    • exit 脚本进程退出
    • break 退出当前循环
    • continue 跳过当前的循环,进入下一个循环

    shell环境

    shell环境概念

    • bash下还可以再重新启动一个shell,这个shell是sub shell,原shell会复制自身给他。在sub shell中定义的变量,会随着sub shell的消亡而消亡。
    • () 子shell中运行
    • $(ls) 表示执行ls后的结果,与``作用一致,不过可以嵌套
    • {} 当前shell中执行
    • $$ 当前脚本执行的pid
    • & 后台执行
    • $! 运行在后台的最后一个作业的pid(进程id)

    shell环境变量

    • shell首先是一个工作环境,有很多变量可以提供我们使用
    • set可以获得当前的所有变量
    • env可以获得可以传递给子进程的变量
    • export aa=bbb 把私有变量导出

    shell输入输出

    • read用来读取输入,并赋值给变量
    • echo print可以输出简单变量
    • >file 将输出重定向到另一个文件
    • >>表示追加 等价于tee -a
    • | 表示管道,也就是前一个命令的输出传入下一个命令的输入

    文件描述符

    • 输入文件-标准输入0
    • 输出文件-标准输出1
    • 错误输出文件-标准错误2
    • curl
    • 使用2>&1>/tmp/tmp</tmp/tmp

    脚本编写

    • 注释
      #以后的语句,shell不会解析
      多行注释可以采用:<<

    • 传入参数

      • $0 表示执行的程序,是相对于执行目录的路径
      • $1,$2,$3分别表示第几个参数,默认shell只支持9个参数,使用shift可以传递更多的参数
      • $@,$*表示所有参数,不含$0
      • ${#*}${#@}表示位置参数的个数
      • 通过${*:1:3},${*:$#}来表示多个参数
    • 函数

      • 语法
      [function] name()
      {
      ..
      }
      
      • function 可以省略。除了可以在脚本文件中使用函数外,还可以shell中定义。这些定义在本次shell结束后消失
      • 如果没有return,返回值是最后一句指令的返回值
    • 执行

    方式一:
    chmod u+x xxx.sh;
    ./xxx.sh
    方式二:
    bash xxx.sh #这种方式会开启一个sub shell
    方式三:
    source xxx.sh  #在当前shell中执行
    
     - eval 可以执行shell原义语句
     - exec 尽量不要使用,这会破坏当前的shell
    
    • 调试
      • bash -x 读取每一句并执行,可以方便的看到执行的语句
      • set -x 在当前shell中调试,set+x还原
      • trap 相关的信号,包括ERR DEBUG等
      • trap cmd ERR

    三剑客

    • grep 数据查找定位(检索)

    • awk 数据切片

    • sed 数据修改

    bash自动化

    自动化交互

    • 批处理并不等于自动化
    • 让交互程序实现非交互执行
    • 借用第三方工具expect

    自动输入方法

    • << 文档字符串。可以实现对序列化输入的操作自动化
    • 管道方式 echo 'password' |passwd
    • 去掉sudo密码提示,也可以通过修改sudoer文件
    • 去掉ssh密码,也可以通过添加认证
    • except

    linux命令

    测试开发应该达到的水平:

    • 文件操作
    • 网络操作 netstat
    • 系统数据分析 ps、top
    • 数据分析能力(linux 三剑客)

    一键搭建web网站

    python -m CGIHTTPServer 8080
    python3 -m http.server

    gnuplot 绘图

    • 通过管道读取数据并绘图

    更多工具

    • 文件系统

      • find、ls、chmod、chown
    • 系统性能统计命令

      • ps netstat top vmstat free
      • netstat -tlnp
      • netstat -tnp
      • /proc 目录保存了所有进程的性能数据

    Andriod常用命令

    • adb

      • adb devices
      • adb kill-server
      • adb tcpip
      • adb connect
      • adb logcat
      • adb bugreport
    • 模拟器的命令

      • 进入emulator所在目录
      • emulator -list-avds
      • emulator@avd
    • adb shell
      adb shell本身就是一个linux shell,可以调用所有的Android内置命令
      adb shell

      • adb shell dumpsys
      • adb shell pm
      • adb shell am
      • adb shell ps
      • adb shell monkey

    iOS命令

    (以后讲)

    快速搜索历史输入

    ctrl+r
    bck-i-search:
    ctrl+a 行首
    ctrl+e 行尾

    实战

    提取对外连接的ip数量

    • 题目解析

      • 目标对象是对外连接的ip,从ngnix上提取
      • netstat命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。
    • bash

    #使用命令netstat 参数-ntp
    netstat -ntp
    #删掉多余的数据行第一行、第二行, 使用sed 1,2d
    netstat -ntp | sed 1,2d
    #提取内容第五部分,使用awk '{print $5}'
    netstat -ntp | sed 1,2d | awk '{print $5}'
    #去掉端口号,使用awk -F ':' '{print $1}'
    netstat -ntp | sed 1,2d | awk '{print $5}' | awk -F ':' '{print $1}'
    #使用sort进行排序,使数据看上去规整一些
    netstat -ntp | sed 1,2d | awk '{print $5}' | awk -F ':' '{print $1}' | sort
    #去除重复的ip,使用uniq 命令删除重复的行,参数-c显示每个ip出现的次数
    netstat -ntp | sed 1,2d | awk '{print $5}' | awk -F ':' '{print $1}' | sort | uniq -c
    #使用wc获取ip的数量,参数-l统计行数
    netstat -ntp | sed 1,2d | awk '{print $5}' | awk -F ':' '{print $1}' | sort | uniq -c | wc -l
    

    提取testhome首页精华帖的点赞数

    • 题目解析

      • 目标对象是testhome首页所有精华帖的点赞数量
      • 使用curl命令可以模拟http请求
    • bash

    #使用curl命令模拟http请求
    curl https://testerhome.com
    #讲请求返回的错误信息仍进黑洞/dev/null
    curl https://testerhome.com 2>/dev/null
    #通过开发者工具-检查元素可以查看到精华帖后面的一个钻石icon属于class="fa fa-diamond"
    curl https://testerhome.com 2>/dev/null | grep "fa fa-diamond"
    #精华帖的list在钻石icon的上一行,使用参数-b1,代表before1行
    curl https://testerhome.com 2>/dev/null | grep -b1 "fa fa-diamond"
    #实际需要的是精华帖列表那一行,通过该行的关键字筛选
    curl https://testerhome.com 2>/dev/null | grep -b1 "fa fa-diamond" | grep "href"
    #每个精华帖的href不一样,同时也是每个精华帖的路径,使用awk进行切割
    curl https://testerhome.com 2>/dev/null | grep -b1 "fa fa-diamond" | grep "href" | awk -F '\"' '{print $4}'
    #因为article是文章集,所以只要topic开头的
    curl https://testerhome.com 2>/dev/null | grep -b1 "fa fa-diamond" | grep "href" | awk -F '\"' '{print $4}' | grep "topics"
    #进入精华帖详情页去获取点赞数,精华帖详情页的路径https://testerhome.com+上面获取的路径列表
    #一行行读取列表,使用while read line;do echo $line;done
    curl https://testerhome.com 2>/dev/null | grep -b1 "fa fa-diamond" |grep "href"|awk -F '\"' '{print $4}'| grep "topics"| while read line;do curl https://testerhome.com$line 2>/dev/null;done 
    #进入了精华帖详情页,根据开发者工具-检查元素可以发现记录点赞数的class是 "fa fa-heart"
    curl https://testerhome.com 2>/dev/null | grep -b1 "fa fa-diamond" |grep "href"|awk -F '\"' '{print $4}'| grep "topics"| while read line;do curl https://testerhome.com$line 2>/dev/null;done |grep "fa fa-heart" 
    #除了话题点赞数之外,还有回复的点赞数,使用 grep "data-type=\"Topic\""去掉回复的点赞数的行
    curl https://testerhome.com 2>/dev/null | grep -b1 "fa fa-diamond" |grep "href"|awk -F '\"' '{print $4}'| grep "topics"| while read line;do curl https://testerhome.com$line 2>/dev/null;done |grep "fa fa-heart" |grep "data-type=\"Topic\""
    #通过awk分割后展示topic、topicid 、点赞数
    curl https://testerhome.com 2>/dev/null | grep -b1 "fa fa-diamond" |grep "href"|awk -F '\"' '{print $4}'| grep "topics"| while read line;do curl https://testerhome.com$line 2>/dev/null;done |grep "fa fa-heart" |grep "data-type=\"Topic\""|awk -F '\"' '{print $8,$10,$4}'
    
    #另一种显示:在curl详情页时把点赞数记为一个变量
    curl https://testerhome.com 2>/dev/null | grep -b1 "fa fa-diamond" |grep "href"|awk -F '\"' '{print $4}'| grep "topics"| while read line;do count=$(curl https://testerhome.com$line 2>/dev/null |grep "fa fa-heart" |grep "data-type=\"Topic\""|head -1|awk -F '\"' '{print $4}');echo "$line 点赞数是: $count";done
    

    从nginx log中提取数据并可视化

    • nginx log在/tmp目录下
    • ls -l *.log搜索日志
    • bash
    #确定目标日志是1206_2.log
    cat 1206_2.log
    #使用sed提取某个时间段的日志
    #-n选项:只显示匹配处理的行(否则会输出所有)
    cat 1206_2.log | sed -n '/07:48:00/,/07:52:00/p'
    #使用gnuplot插件进行数据展示(gnuplot不会,随便看看吧)
    cat 1206_2.log | sed -n '/07:48:00/,/07:52:00/p' | gnuplot -e "set terminal dumb;set datafile |separator ' ';set timefmt '[%d/%b/%Y:%H%:%M:%S]';set ydata time;set format y '%H%M'%S;|plot '<cat' using 8:4 with lines"
    

    相关文章

      网友评论

          本文标题:bash语言笔记

          本文链接:https://www.haomeiwen.com/subject/uldddctx.html