美文网首页
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语言笔记

    测试开发的shell水平 linux文件操作网络操作 netstat系统数据分析 ps、top数据分析能力(lin...

  • bash 语言 学习笔记

    前言 大部分人都用过终端命令行。有的时候需要繁琐的输入同样的命令,我们可以编写自己的脚本来完成这个工作。 指定解释...

  • bash 笔记

    bash是许多linux系统默认的shell(命令行工具)。 cmd和powershell是window系统默认的...

  • bash笔记

    第一行#!/bin/bash 读取命令并保存到变量:dir=\pwd`或者dir=$(pwd)` 数组: arra...

  • vscode 界面设置中文,默认终端改为git bash

    1.修改默认语言设置 2.下载中文语言包 3.设置git bash为终端,要对应的git bash.exe的目录哦~

  • Bash脚本编程(2)——编程入门

    @(Bash)[编程入门] 1. Bash中的变量 1.1 变量类型 字符型 数值型 整型 浮点型 语言类型: 强...

  • 目前涉及到并且需要掌握的知识

    语言 java,mysql,python,bash,guava 框架 spring,mybatis,git,mq,...

  • Linux shell

    shell既是命令也是编程语言,是用户与linux内核交互的平台。 熟悉bash命令 bash只是shell的一种...

  • bash的三元操作符

    类似其他高级语言的(?:)操作符: 如果用标准的bash语句来实现就是:用if语句: 用case语句: 在bash...

  • Bash 笔记[一]

    最近看Caffe的shell脚本,记一些shell相关的用法。 1. > 和 >> 的区别 > 用于重定向程序的输...

网友评论

      本文标题:bash语言笔记

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