前言
今天在做一些测试的工作,无非就是把一些基础的测试命令,一条条敲到terminal去执行看是否能够成功。因为有的测试5、60条。这就很烦了,一次两次还好,这尼玛一月四次,比大姨妈来的频率还高?作为一个程序员,无法忍受。于是想着整个脚本试一下。
我的最开始第一版是把我所有要执行的命令,放进了一个文件,然后直接运行这个脚本即可。但是每次执行都会打印很多的信息,这样我要一个一个用眼睛去看这些有没有执行成功,好吧,不太优雅。
想着我要是能把执行的信息放到一个log文件,再通过搜索执行成功的关键词然后打印出成功了多少,失败了多少,这样就太好了。
之前学了关于shell的东西,但是学习嘛就是拿来忘记的,哈哈哈。
还是得通过需求和实践项目训练才得行。
1.0版本
这个版本就是将所有要执行的测试命令,一条条copy上去,当脚本运行起来的时候,会一条条执行,但是这个执行测试会产生大量的日志。如果在这个日志中获取到我们的关键结果才是我们在意的。
根据进一步的需求,将测试的结果放到一个log文件。
根据log文件的关键信息,记录哪些成功,哪些失败了。
2.0版本
在2.0的实现之前,先根据我的需求拆成几个知识点学习一下。
1、shell怎么写函数?
因为我想实现将执行的命令产生的日志都到一个log文件中保存。
1-函数定义
有两种格式可以用来在 bash shell 脚本中创建函数。
- 第一种格式采用关键字 function,后跟分配给该代码块的函数名。
function name { commands }
- 第二种格式更接近于其他编程语言中定义函数的方式。
name() { commands }
- name:定义了赋予函数的唯一名称。脚本中定义的每个函数都必须有一个唯一的名称。
- commands:构成函数的一条或多条 bash shell 命令。在调用该函数时,bash shell 会按命令在 函数中出现的顺序依次执行,就像在普通脚本中一样。
2-函数使用
要在脚本中使用函数,只需要像其他 shell 命令一样,在行中指定函数名就行了。
测试示例:
onlylove@ubuntu:~/my/shell/01$ ls test.sh onlylove@ubuntu:~/my/shell/01$ cat test.sh #!/bin/bash function f1 { echo "hello world f1" } f2(){ echo "hello world f2" } f1 f2onlylove@ubuntu:~/my/shell/01$ onlylove@ubuntu:~/my/shell/01$ ./test.sh hello world f1 hello world f2 onlylove@ubuntu:~/my/shell/01$
3-返回值
1、默认退出状态码
默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束 后,可以用标准变量 $? 来确定函数的退出状态码。
2、使用 return 命令
bash shell 使用 return 命令来退出函数并返回特定的退出状态码。return 命令允许指定一个 整数值来定义函数的退出状态码,从而提供了一种简单的途径来编程设定函数退出状态码。
特别说明:
- 函数一结束就取返回值;
- 退出状态码必须是 0~255。
- 如果在用 $? 变量提取函数返回值之前执行了其他命令,函数的返回值就会丢失。
3、例子
#!/bin/bash function f1 { echo "hello world f1" } f2(){ echo "hello world f2" } f1 echo "f1 The exit status is: $?" f2 echo "f2 The exit status is: $?"
onlylove@ubuntu:~/my/shell/01$ ls test.sh onlylove@ubuntu:~/my/shell/01$ ./test.sh hello world f1 f1 The exit status is: 0 hello world f2 f2 The exit status is: 0 onlylove@ubuntu:~/my/shell/01$
4-小结
到这里我们实现的目的就到了,克制自己的好奇心,学多了用不到又忘了,哈哈哈
那我们就可以定义一个函数
f2() { echo "hello world f1" echo "hello world f1" echo "hello world f1" echo "hello world f1" echo "hello world f1" } f2 > test.log
实验室电脑测试一下。
2、shell怎么在一个文件中筛选关键词
这个就比较麻烦了,因为我们的目的是在log中找到success这些关键词,那么有些基础知识在所难免了。
三剑客就是普通的命令,有的把他们叫做工具,在我看来都一样。而正则表达式就好比一个模版。三剑客能读懂这个模版。就这么简单。注意只有三剑客才能读懂这个模版哦!
1、Linux三剑客–>
这个第一次接触是在当时为了考研复试的时候,哈哈哈后来就忘了。
- grep擅长取行、
- sed擅长取行和修改、
- awk擅长取列。
1-awk
报告生成器,格式化文本输出,有多种版本:New awk(nawk),GNU awk( gawk)
注意:program部分只能用单引号,不能用双引号,否则会报错.
awk [options] 'program' file
1、常用命令选项 -F 指定分隔符,默认空格或Tab键 -f 调用awk脚本 -v 调用外部shell变量 2、awk内置变量 $1..$n 指定分隔符号对应的值 $0 当前行的内容 $NF 最后一列 NF 指定分隔符号后,行的列数 NR 当前行的行号 FS 保存或设置字段分隔符 FNR 保存当前文件的行数 FILENAME 保存当前的文件名 ENVIRON 调用shell环境变量 awk '{print $0}' a.txt #打印文件所有内容($0代表整行) awk '{print $1,$2}' a.txt #打印第1列和第2列的内容 awk -F":" '{print $1,$2}' OFS="," a.txt #以:为输入分隔符并且以,为输出分隔符打印第1列和第2列的内容 awk -F"," '{print NR,$NF}' a.txt #以,为分隔符并打印行号和最后一列 awk -F"[ .]" '{print $(NF-1)}' OFS="\t" a.txt #以空格或.为输入分隔符并以制表符为输出分隔符打印倒数第二列 3、正则表达式 /正则/ 匹配正则(行) ~/正则/ 匹配正则(列) !~/正则/ 不匹配 awk -F":" '$1~/root/ {print $0}' /etc/passwd awk -F":" '$1!~/root/ {print $0}' /etc/passwd awk -F":" '$1~/^ro/ {print $3}' /etc/passwd awk -F":" '$1~/[0-9]/ {print $1,$6}' /etc/passwd 4、数值比较 awk -F":" '$3==0{print $0}' /etc/passwd awk -F":" '$3!=0{print $0}' /etc/passwd awk -F":" '$1=="root"{print $0}' /etc/passwd 5、逻辑比较(多个条件) 逻辑与 && 多个条件同时成立 逻辑或 || 多个条件有一个成立 逻辑非 ! 取反 awk -F":" '$7=="/bin/bash" && $3<500{print $0}' /etc/passwd awk -F":" '$7=="/bin/bash" || $3<500{print $0}' /etc/passwd
2-sed
sed是一种流编辑器,作用是实现对文件的增删改查,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’ 的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
sed [option]... 'script' inputfile
sed 流编辑器,实现对文件的增删改查 选项: -n 屏蔽默认输出 -i 直接修改源文件 -e 可指定多个处理动作 -r 支持扩展表达式 {} 可组合多个命令,以;分隔 -f 使用sed脚本 定址符: p 打印行 d 删除行 s 字符串替换 1 对第1行处理 1,3 对第1到3行处理 1,+3 对第1行后面3行处理 1~2 对1,3,5,7……行处理 1,$ 对1行到最后1行处理 /aa/,/bb/ 对a行到b行处理 /aaa/,9 对a行到第9行,若前9行没有,会显示后9行匹配的行
举例子:(注意:sed增删改如果不加 -i 选项的话只是预览模式,并没有真的增删改) 增: i 行前插入 a 行后插入 sed -i '2ixx' m.txt 在第2行前插入行xx sed -i '3,6ixx' m.txt 在第3-6行每行前插入xx sed -i '2axx' m.txt 在第2行后插入xx sed -i '/^yy/axx' m.txt 在yy开头的行后插入xx 删: sed -i '3,5d' a.txt 删除第3到5行 sed -i '/xml/d' a.txt 删除所有包含xml的行 sed -i '/xml/!d' a.txt 删除不包含xml的行 sed -i '/^xml/d' a.txt 删除以xml开头的行 sed -i '$d' a.txt 删除最后1行 sed -i '/^$/d' a.txt 删除所有空行 sed -i '/^$/{n;/^$/d}' a.txt 删除重复空行,连续两个空行只保留一个 sed -i -r'/a|b/d' a.txt 删除a或b的行 sed -i '2,~2d' a.txt 删除2行到2的倍数行 改(加-i选项才会真的修改源文件): c 行替换 s 字符串替换 g global(全局替换) sed -i '2cxx' m.txt 第2行替换成xx sed -i '3,6cxx' m.txt 第3到6行替换成1行xx sed -i -e '3cxx' -e '6cxx' m.txt 第3行和第6行替换成xx sed -i '2cxx\nyy' m.txt 第2行替换成xx并换行写上yy(\n代表换行) sed -i 's/test/demo/g' a.txt 将所有的test换成demo(常用) sed -i 's/#ipv6=no/ipv6=yes/g' test.txt 将test.txt文件里的#ipv6=no改成ipv6=yes(sed的这种用法经常用来更改配置文件里的内容) sed -i 's/a//g' a.txt 删除所有行的a sed -i '4,7s/^/#/' a.txt 4到7行加#号 sed -i '4,7s/^#//' a.txt 4到7行去掉#号 sed -i 's/a/B/ig' a.txt 所有行的a替换成B(不区分大小写) 查: sed –n ’20,30p’ b.txt 打印20到30行 sed -n '3p;6p' a.txt 打印第3和6行 sed -n '3,+6p' a.txt 打印第3行及其后6行 sed -n '/^bin/p' a.txt 打印以bin开头的行 sed -n 'p;n' a.txt 打印奇数行,n表示读下一行(隔行) sed -n 'n;p' a.txt 打印偶数行,n表示读下一行(隔行) sed -n '8,${n;p}' a.txt 打印8行到末尾所有的偶数行 sed -n '$=' a.txt 打印文件的行数 sed -n '/a/{=;p} ' b.txt 显示行号 sed -n l aaa.jpg 打印不可见字符
3-grep
文本过滤(模式:pattern)工具,grep, egrep
grep [options] pattern [file...]
--color=auto 对匹配到的文本着色显示 -v 显示不被pattern匹配到的行 -i 忽略字符大小写 -n 显示匹配的行号 -c 统计匹配的行数 -o 仅显示匹配到的字符串 -q 静默模式,不输出任何信息 -A # after, 后#行 -B # before, 前#行 -C # context, 前后各#行 -e 实现多个选项间的逻辑or关系 grep –e ‘cat ’ -e ‘dog’ file -w 匹配整个单词 -E 使用ERE,相当于egrep -F 相当于fgrep,不支持正则表达式
举例子: grep root passwd.txt #查找文件内容包含root的行 grep -i root passwd.txt #查找文件内容包含root(忽略大小写)的行 grep -v root passwd.txt #查找文件内容不包含root的行 grep -w "root" passwd.txt #查找文件内容包含整个单词"root"的行 grep ^s passwd.txt #查找以s开头的行 grep n$ passwd.txt #查找以n结尾的行 egrep "^([0-9]{1,3}.){3}[0-9]{1,3}$" log.txt | sort | uniq -c #找出log文件中的所有ip地址并统计每个ip出现的次数
2、正则表达式–>
所谓的正则表达式我个人理解就是正规的表示方法。他是用简单的方法来实现强大的功能,所以深受计算机爱好者的使用。
- 字符类
.:匹配任意单个字符 []:匹配中括号内的任意一个字符 -:在[ ]中括号内表示字符的范围 ^:位于[ ]中括号内的开头,匹配除括号内的字符之外的任意一个字符
- 数量限定符
?:匹配其前面的字符0次或1次 +:匹配其前面的字符至少1次 *: 匹配其前面的字符任意多次 {N}:匹配其前面的字符N次 {N,}:匹配其前面的字符至少N次 {,M}:匹配其前面的字符最多M次 {N,M}:匹配其前面的字符N到M次
- 位置限定符
^:匹配行首的位置 $:匹配行尾的位置 \<:匹配单词开头的位置(比如\<ro匹配root或robot) \>:匹配单词结尾的位置(比如ot\>匹配root或robot) \<word\>:精准匹配单词word
大概记录了一下,明天去实战一下!!!
参考前辈的blog链接如下:
https://blog.csdn.net/weixin_44681349/article/details/125015316