Linux 与 Shell 教程
操作系统历史与 Linux 与 Shell 环境搭建介绍
系统信息
Linux 常用命令
命令分类
- 文件:everything is file
- 进程:文件的运行形态
- 网络:特殊的文件
文件
- 磁盘与目录:df、ls、cd、pwd、$PWD
- 文件编辑:交互编辑 vim、流式编辑器 sed
- 文件权限:chmod、chown
- 文件搜索:find
- 文件内容:cat、more、less、grep
- 特殊文件:软链、socket:进程通讯、管道:进程通讯
文件权限
- ls -l 查看权限
- 文件、目录
- 用户、组
- 读、写、执行、SUID、SGID
- chmod:修改归属者
- chgrp:修改归属组
进程
- top
- ps
网络
netstat -tlnp
netstat -tnp
mac 与 linux 不一致:netstat -p tcp -n -a
Shell Piping 管道
Shell 输入输出
- Read 用来读取输入,并赋值给变量
- echo , printf 可以简单输出变量
- > file 将输出重定向到另一个文件
- >> 表示追加 等价于 tee -a
- < file 输入重定向
- | 表示管道,也就是前一个命令的输出传入下一个命令的输入
文件描述符
输入文件-标准输入0
输出文件-标准输出1
错误输出文件-标准错误2
使用 2>&1 >/tmp/tmp < /tmp/tmp
文件描述符
管道
把不同程序的输入和输出连接
可以连接更多命令
-
常见的组合命令 Linux 三剑客
echo hello world | read x;echo $x echo hello world | {read x;echo $x;} echo hello world | while read x;do echo $x;done
管道
Linux 三剑客 grep + awk + sed
Linux 三剑客介绍
- grep
- global search regular expression(RE) and print out the line
- 基于正则表达式查找满足条件的行
- awk
- 名字来源于三个作者的名字简称
- 根据定位到的数据行处理其中的分段
- sed
- stream editor
- 根据定位到的数据行修改数据
Linux 三剑客的价值
- 三剑客
- grep 数据查找定位
- awk 数据切片
- sed 数据修改
- 类比 SQL
- grep=select * from table like '%xx'
- awk=select field from table
- sed=update table set field=new where field=old
grep
- grep pattern file
- grep -i pattern file 忽略大小写
- grep -v pattern file 不显示匹配的行
- grep -o pattern file 把每个匹配的内容用独立的行显示
- grep -E pattern file 使用扩展正则表达式
- grep -A -B -C pattern file 打印命中数据的上下文
- grep pattern -r dir / 递归搜索
pattern 正则表达式
- 基本表达式(BRE)
- ^ 开头 $ 结尾
- [a-z] [0-9]区间,如果开头带有 ^ 表示不能匹配区间内的元素
- *0个或多个
- ·表示任意字符
- 基本正则(BRE)与扩展正则的区别(ERE)
- ? 非贪婪匹配
- 一个或者多个
- ()分组
- {}范围约束
- | 匹配表达式的任何一个
演练
curl https://testerhome.com | grep -o 'http://[a-zA-Z0-9\.\-]*'
curl https://testerhome.com 2>/dev/null | grep Appium | grep -v Python
awk
- 介绍
- Awk 是 linux 下的一个命令,同时也是一种语言解析引擎
- Awk 具备完整的编程特性。比如执行命令,网络请求等
- 精通 awk,是一个 linux 工作者的必备技能
- 语法
- awk 'pattern{action}'
awk pattern 语法
- awk 理论上可以代替 grep
- awk 'pattern{action}'
- awk 'BEGIN{}END{}' 开始和结束
- awk '/Running/' 正则匹配
- awk '/aa/,/bb/' 区间选择
- awk '$2~/xxx/' 字段匹配
- awk 'NR==2' 取第二行
- awk 'NR>1' 去掉第一行
awk 内置变量
- PS 字段分隔符
- OFS 输出数据的字段分隔符
- RS 记录分隔符
- ORS 输出字段的行分隔符
- NF 字段数
- NR 记录数
awk 的字段数据处理
- -F 参数指定字段分隔符
- BEGIN{FS="_"} 也可以表示分隔符
- $0 代表当前的记录
- $1 代表第一个字段
- $N 代表第 N 个字段
- $NF 代表最后一个字段
- $(NF-1) 代表倒数第二个字段
awk 字段分割
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' \
| awk -F/ '{print $1,$2,$3,$4}'
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' \
| awk 'BEGIN{FS="/"}{print $1,$2,$3,$4}'
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' \
| awk 'BEGIN{FS="/|-"}{print $1,$2,$3,$4}'
- 修改 OFS 和 ORS 让 $0 重新计算
echo $PATH | awk 'BEGIN{FS=":";OFS=" | "}{$1=$1;print $0}' echo $PATH | awk 'BEGIN{RS=":";ORS="^"}{print $0}'
awk 行处理
- 把单行拆为多行
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' echo $PATH | awk 'BEGIN{RS=":"}{print NR,$0}' echo $PATH | awk 'BEGIN{RS=":"}END{print NR}'
- 多行组合为单行
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' | awk 'BEGIN{ORS=":"}{print $0}'
数据计算
echo '1,10
2,20
3,30' | awk 'BEGIN{a=0;FS=","}{a+=$2}END{print a/NR}'
awk 的词典结构
- 提取包含“9期”但是并不包含“学员”的记录
awk -F,' /9期/{if(member[$1]!=1) d[$1]=$0} /学员/{member[$1]=1;delete d[$1]} END{for(k in d) print d[k]} ' file
sed
- sed [addr]X[options]
- -e 表达式
- sed -n '2p' 打印第二行
- sed 's#hello#world#' 修改
- -i 直接修改源文件
- -E 扩展表达式
- --debug 调试
pattern
- 20 30,35 行数与行数范围
- /pattern/ 正则匹配
- //,// 正则匹配的区间,第一个表示开始命中,第二个表示结束命中,类似开闸放水
action
- d 删除
- p 打印,通常结合 -n 参数:sed -n '2p'
- 查找替换:s / REGEXP / REPLACEMENT / {FLAGS}
- 分组匹配与字段提取:sed 's#([0-9]*) | ([a-z]*)# \1 \2#'
sed
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' | sed 's# / #----#g'
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' | sed -n '/^\ /bin/,/sbin/p'
sed -i '.bak' -e " -e "
三剑客实战
- 日志数据搜索
- 找出 log 中的 404 500 的报错
less nginx.log | awk '$9~/500|404/{print $0}'
- 找出 500 错误时候的上下文 考察 grep 高级用法
grep -B 2 " 500 " nginx.log
- 找出 log 中的 404 500 的报错
- 日志数据统计
- 找出访问量最高的 ip,取出 top10 统计分析
cat nginx.log | awk '{print $1}' |sort|uniq -c|sort -nr|awk 'NR<11'|awk '{print $2}'
awk '{print $1}' nginx.log | sort | uniq -c | sort -nr | head -10
- 找出访问量最高的 ip,取出 top10 统计分析
- 数据文件修改
- 找出访问量最高的页面地址 借助于 sed 的统计分析
url_summary() { # 管道符后面可以换行 less nginx.log | awk '{print $7}' | # sed 的多个表达式合并 sed -e 's/\?.*//g' \ -e 's/\/avatar\/[0-9]*'/\/avatar\/int/g' \ -e 's/\/topics\/[0-9]*/\/topics\/int/g'\ -e 's/\/replies\/[0-9]*/\/replies\/int/g' | sed -e 's/\/[0-9a-z\-]*\.png/\/id.png/g' | sed -e 's/\/[0-9a-z\-]*\.jpg/\/id.jpg/g' | sed -e 's/\/[0-9a-z\-]*\.jpeg/\/id.jpeg/g' | sed -e 's/\/[0-9a-z\-]*\.gif/\/id.gif/g' | sort | uniq -c | sort -nr }
url_summary() { less /tmp/nginx.log | awk '{print $7,$(NF-2)}' | sed -e 's#/[0-9]*\.#_int_#' \ -e 's#/[0-9]*$#/_int_#' \ -e 's#/[a-z0-9\-]*\.#/_id_#' \ -e 's#?[^ ]*##' \ -e 's#/[0-9]*/#/_int_/#g' \ -e 's#/[0-9]\{3,\} #/_int_end_ #' | awk '{s[$1]+=$2;n[$1]+=1}END{for(k in s) print k,s[k]/n[k]}' | sort -n -k2 | less }
- 找出访问量最高的页面地址 借助于 sed 的统计分析