shell 壳
操作系统与应用程序之间的一个命令翻译工具
sh bash zsh
一、常用命令
用--help
(1)head 默认获取文件前10行 ,前三行用 head -3 前几个字节,用head -c 3 前三个字节
more是分页的,cat不分页
(2)tail 默认获取文件后 10行, tail -3 尾部三行
获取中间某几行的命令,获取5-8行的数据,可以使用 head -8 文件名 | tail -3
(3)cut 分割, 提取文件指定的列 -d ,获取第一列和第三列,以冒号分隔。 cut -d“:“ -f1,3 文件名 结果展示例如 root:admin。默认以tab键进行分割(不支持不规律的空格) -d 指定分割符 -f指定获取的列号。
(4)uniq 去重 要和sort 联合使用
去掉重复的内容,选项, -d 仅打印有重复的元素(duplicate) -c打印元素重复的个数,
有管道符的情况下,后面的命令不需要 加上文件名,使用这个去重的时候,先要排序,然后再去重,如果不排序,只能去重两个相邻的是否重复,所以要和sort 联合使用。sort -r 文件名 | uniq -d 。 sort -r 文件名 | uniq -c 打印重复元素的个数。
head -50 test.log | cut -d" " f4 | sort | uniq -c 打印出前50行里去重的用户名和个数
head -50 test.log | cut -d" " f4 | sort | uniq ,获取前50行日志里的用户名
(5)sort 排序默认以ASCII码数值从小到大排序。 选项 -n 以数值大小排序 -r倒序 -t 指定分隔符,默认为空格。 -knum指定以某个字段来排序
sort -r test.txt
(6)wc (word count)
计算文本数量
选项 wc-l打印行数
wc -w打印单词数
wc -c打印字节数
wc -L打印最长字节数
二、变量
分类
定义变量
1、本地变量
username="tester01"等号两侧不能有空格
打印这个变量,echo $username
可以用一个命令作为变量的值
one_var=$(ls /)
echo $one_var
2、全局变量
export user="tester02" 直接声明一个全局变量
3、内置变量
env查看所有的环境变量
$0获取当前执行的shell脚本文件名、包括脚本路径
$n 获取当前执行的shell脚本的第n个参数值,n=1.....9,如果n>9就要用大括号括起来{10}
$# 获取当前shell命令行中参数的总个数
$?获取执行上一个指令的返回值(0为成功,非0为失败)
4、查看变量
echo $user 或者 echo "$user" ,但是echo '$user'是不行的,单引号展示的是所见即所得
echo "${user}" 最常用
在shell脚本中不能使用 echo $user ,在脚本中 必须使用echo "${user}"
三、数值运算
1、支持的运算
+ - * / % < <= > >= = !=
2、方式一
echo $((1 + 1)) 用两个(())
$(算数表达式)
变量可以不加$
one_number=10
two_number=20
echo $((one_number + two_number))
建议使用 这种方式
3、方式二
expr 算数表达式
echo "$(expr 20 \* 10)" ,这个* 需要转义
四、条件表达式
1、返回值
条件成立,返回0
条件不成立,返回1
2、逻辑表达式
&& 和 ||
如果前面的成立了,才会执行后面的
[ 1== 1 ] && echo "success" 如果1==1成立了,就会执行后面的
[ 1==1 ] || echo "success" 如果1==1成立了,就不会执行后面的
[ "${user}" == "tester" ] && echo "yes" || echo "no" 如果成立 执行 echo “yes”,否则执行echo “no”
3、文件表达式
-f 判断输入内容是否是一个文件
-d判断输入内容是否是一个目录
-x 判断内容是否可执行
-e判断文件是否存在
4、数值操作符
-eq 相等
-gt 大于
-lt 小于
-ne 不等于
5、字符串比较
str1 == str2 str1和str2字符串内容一致
str1 != str2 str1和str2 字符串内容不一致,!表示相反的意思
五、shell脚本格式
1、格式要求
在文件首行指定执行shell的程序以及相关说明
#!/bin/bash
#Author:testor
#Date:2022-01-01
shell脚本文件后缀,建议命令为.sh
脚本执行失败时,使用exit返回非零值,来退出程序
默认缩进4个空格
shell脚本的命令简单、有意义
注释
单行注释
#
六、函数
1、格式
bash 文件名.sh
格式一:
函数名()
{
命令1
命令2
}
格式二:
function test
{
命令1
命令2
}
test(){
echo "Hello ,${LOHNAME}, today is ${date}"
}
2、参数
函数体调用参数
函数名(){
函数体 $n
}
调用函数给函数传参数
函数名 参数
调用变量
- #!/bin/bash
- #Author:tester
- #Date: 2022-1-18
- #command line parameter
-
- #$REPLY
-
- read -p "请输入你的姓名:" name
- read -p "请输入你的年龄:" age
-
- function info
- {
- echo -e "你的姓名为: ${name}\n你的年龄为: ${age}"
- }
如何接收命令行传过来的参数
- #!/bin/bash
- 传参
- echo "第一个参数为: $1"
- echo "第二个参数为:$2"
- ${10} 大于10个参数时候,这么写
- echo "shell脚本名字为:$0"
- echo "shell脚本的参数个数为:$#"
- echo "shell脚本的所有参数: $*"
- #!/bin/bash
- function test
- {
- echo -e “您当前的名字:$1\n你的年龄是:$2“
- }
- test"土豆" "地瓜"
第一个实参会被$1接收,第二个实参会被$2接收
- #!/bin/bash
-
- read -p "请输入您的姓名:" name
- read -p "请输入您的年龄:" age
-
- function test
- {
- ehco -e "你的姓名为:$1\n你的年龄为:$2"
- }
- test "${name}" "${age}"
脚本中如何接收命令行参数
- #!/bin/bash
-
- function test
- {
- echo -e "您的姓名为:$1\n您的年龄为:$2"
- }
-
- test $1 $2
bash function_params.sh "姓名" 18
3、input,提示用户从键盘中输入
read
read value
read -p prompt value
七、流程控制
1、if
if [ 条件1 ]
then
指令1
elif[ 条件2 ]
then
指令2
else
指令3
fi
条件表达式0 为真,非0为假,如果不使用命令行接收,用${REPLY}这个变量进行接收
-gt 大于70
- #!/bin/bash
-
- read -p "请输入你的年龄:"
-
- if[ "${REPLY}" -gt 70 ]
- then
- echo "如果大于70了,就要锻炼"
- elif[ "${REPLY}" -gt 18 ]
- then
- echo "恭喜你"
- else
- echo "小于18的,该干啥干啥"
- fi
-
2、for
格式一:
for 值 in 列表
do
执行语句
done
ls / 展示跟目录下的列表作为一个变量,赋值给dir
- #!/bin/bash
-
- dir=$(ls /)
- index=1
-
- for i in ${dir}
- do
- echo "第${index}个文件为: ${i}"
- index=$((index+1))
- done
调试shell 脚本使用 bash -x 脚本名.sh
格式二:
max=10
for ((i=1;i<=max;i++))
do
echo "$i"
done
- #!/bin/bash
-
- max=10
-
- for((i=1;i
- do
- echo"${i}"
- done
3、while
只要条件满足,就一直循环
while 条件
do
执行语句
done
- #!/bin/bash
- #Author:
- #Date:2022-01-01
-
- read -p "请输入一个数字:"a
- while [ "${a}" -lt 20 ]
- do
- echo "${a}"
- a=$((a+1))
- done
4、until
只要条件不满足,就一直循环
until 条件
do
执行语句
done
5、case
case 变量名 in
值1)
指令1
;;
值2)
指令2
;;
值3)
指令3
;;
*)
指令4
;;
esac
- #!/bin/bash
-
- case $2 in
- +)
- echo "$1 + $3= $(($1+$3))"
- ;;
- -)
- echo "$1 - $3= $(($1-$3))"
- ;;
- \*)
- echo "$1 / $3= $(($1/$3))"
- ;;
- /)
- echo "$2 can not calcaulate"
- ;;
-
- esac
bash test.sh 10 \* 5
10*5=50
八、文本处理三剑客
1、grep
两种形式
grep
选项 含义
-i 忽略大小写
-c 只输出匹配行的数量
-n 显示行号
-r 递归搜索
-E 支持拓展正则表达式
-w 匹配整个单词
-l 只列出匹配的文件名
-F 不支持正则,按字符串字面意思进行匹配
例如 grep “$USER” /etc/passwd && echo "$USER existed" || echo "$USER not existed"
2、sed
sed stream editor 流编辑器,sed把处理的内容(文件),直到文件末尾。
sed 功能
s 替换 substitute sub
p 显示 print
d 删除 delete
cai 增加c/a/i
sed命令执行过程
sed -n ‘3p’ test.txt
sed核心应用
1)sed 查找p
查找格式
‘1p’ ‘2p’ 指定行号进行查找
‘1,5p’ 指定行号范围查找
'/lidao/p' 类似于grep ,过滤
‘/10:00,/11:00/p’ 表示范围的过滤
sed -n '4, $p' test.txt 表示第4行到最后一行
wc -l access.log 看有多少行
sed -n '/11:02:30/p' access.log 表示范围的过滤
sed -n '/11:02:29/,/11:02:30/p' access.log | wc -l 查看从11:02:29这秒,到11:02:30这秒的数据总共有多少行。
如果结尾的点不正确,会一致显示到文件最后一行数据。
2)sed -删除
sed '3d' test.txt 删除第3行
sed '2,3d' test.txt 删除2-3行
sed '/li/d' test.txt 删除文件中的匹配到li的行
删除文件中的空行和包含井号的行
sed -r '/^$|#/!d' 遇到空行或井号的不删除
sed -nr '/^$|#/!p' 遇到空行或井号的不显示行号
3)sed - 增加cai
命令
c replace 替代这行的内容
a append 追加,向指定行的下一行或每一行追加内容
i insert插入,向指定的行上一行或每一行插入内容()
sed '3a 33,lidao996,uf' test.txt 在第3行的下一行追加一行
sed '3i 44,dd,rr' test.txt 在第3行的上一行插入一行内容
sed '3c 44,55,77' test.txt 把第3行的内容替换
向文件中追加多行内容
sed '$a sdf \nsdasd \n' 向最后一行追加sdf sdasd
4)sed -替换s substitute替换
g 全局替换,加上g后,代表全局替换每行所有匹配的内容
sed 's#[-0-9]##g' test.txt
sed默认只替换每行第一个匹配的内容
sed 's#[0-9]##' test.txt
sed 后向引用也叫反向引用
口诀,先保护,再引用
替换格式
s###g
s///g
s@@@g
echo 123456 | sed -r 's#(.*)#<\1>#g'
<123456>
反过来顺序
echo old_test | sed -r 's#(^.*)_(.*$)#\2_\1#g'
test_old
3、awk
awk一门语言,类似于c语言,过滤统计,计算有关的,过滤,统计日志。
行与列
名词 awk中叫法 说明
行 记录record 每一行默认通过回车分割的
列 字段,域field 每一列默认通过空格分割的
awk中行和列结束标记都是可以改的
awk 内置变量
1)取行:
NR==1 , 取出某一行
NR>=1 && NR<=5 ,取出1到5行范围
awk 'NR==1' test.txt
符号 > < >= <= == !=
2)取列
-F 制定分隔符,制定每一列结束标记(默认是空格 tab键)
$数字,取出某一列, 例如 awk ‘{print $5}’,在awk中$内容,表示取出某一列。
$0 整行的内容,
{print}
NF Number of Field 每行有多少列, $NF表示最后一列。
awk -F: '{print $1, $NF}' /test.txt | column -t
使用awk调换passwd 第1列和最后一列内容,然后显示每一行内容(调换后的)
awk -F: '{print $NF, $2, $3,$4,$5, $6,$1}' /etc/passwd
FS -F: === -v FS=:
OFS
九、日志分析系统演练
1、统计每位测试人员执行用例的总数
2、分别统计每位测试人员执行用例成功和失败的总数
3、将1、2合并,同时分别统计每位测试人员执行用例CRITICAL、ERROR日志等级数以及所有测试人员每项总数
4、使用shell脚本来实现,并显示菜单,选择不同的选项则打印不同的内容