linux进阶学习笔记

本文档详述了Linux进阶知识,包括wc命令、输入/输出重定向、文件描述符、lsof命令的使用,以及BRE和ERE正则表达式。此外,还介绍了如何在Linux环境中进行实战操作,如查找用户登录、错误日志分析、URL统计等,旨在提升Linux操作技能。

一、Linux进阶补充

1.wc命令

语法:wc [选项] 文件…
说明:该命令统计给定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。

wc -l file 统计行数
wc -w file 统计单词数
cat file | wc -c 统计字符数
wc file 分别打印出文件的行数、单词数和字符数
find test/ -name "*.js" |wc -l 统计test目录下,js文件数量

2.输入/输出重定向

命令说明
> file将输出重定向到另一个文件file
>> file将输出以追加的方式重定向到file
< file将输入重定向到file

3.文件描述符

文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,当某个程序打开文件时,操作系统返回相应的文件描述符,程序为了处理该文件必须引用此描述符。程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。如果此时去打开一个新的文件,它的文件描述符会是3。
标准文件描述符号如下:

文件描述符用途POSIX名称stdio流
0标准输入(数据输入到程序中)STDIN_FILENOstdin
1标准输出(程序打印的数据,默认为终端)STDOUT_FILENOstdout
2标准出错(对于错误消息,也默认为终端)STDERR_FILENOstderr

在这里插入图片描述
举例:
(1)把当前的标准输出重定向到test文件中

[root@localhost ~]# echo 'test01' 1> test
[root@localhost ~]# cat test
test01

(2)把当前的标准输入重定向到test文件中

#接上面操作
[root@localhost ~]# read user 0< test
[root@localhost ~]# echo $user
test01  #user变量输入为test里的文本内容

(3)把当前标准出错输入到重定向test文件

[root@localhost ~]# ls -l test111
ls: 无法访问test111: 没有那个文件或目录
[root@localhost ~]# ls -l test111 2> error.txt #STDERR是流号2,使用该种数字来标识流。如果在>运算符之前放置一个数字,则它将重定向该流(如果不使用那样使用数字,则默认为流1)。
[root@localhost ~]# cat error.txt 
ls: 无法访问test111: 没有那个文件或目录

(4)分配其他的文件描述符

[root@localhost ~]# exec 6>test #文件描述符6指向test文件
[root@localhost ~]# echo 'test 6' 1>&6  #不像描述符1,所有的输出都会自然找它,所以像找描述符6的时候要用&来引用它。
#这条命令就将输出指向到了描述符6,然后描述符6又将内容重定向到test文件。
[root@localhost ~]# cat test
test 6

详细可参考:Linux 文件描述符详解,最后还附有管道和重定向之间的区别。

4.lsof命令

lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。
lsof语法格式是: lsof [options] filename

在终端下输入lsof即可显示系统打开的文件,输出内容包含信息如下:
在这里插入图片描述
COMMAND:程序的名称
PID:进程标识符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件
TYPE:文件类型,如 DIR、REG 等
DEVICE:以逗号分隔设备编号
SIZE:文件的大小(bytes)
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称

常用的参数列表:
lsof filename 显示打开指定文件的所有进程
lsof -a 组合多个选项,选项间默认是或的关系,-a可以将选项间关系变为与
lsof -c <进程名> 输出指定进程所打开的文件
lsof -u username 显示所属user进程打开的文件
lsof -g gid 显示归属gid的进程情况
lsof +d /DIR/ 显示目录下被进程打开的文件
lsof +D /DIR/ 同上,但是会搜索目录下的所有目录,时间相对较长
lsof -d FD 显示指定文件描述符的进程
lsof -n 不将IP转换为hostname,缺省是不加上-n参数

-i 选项用来查看被打开的和网络相关的文件,其参数的格式如下:
[46][protocol][@hostname|hostaddr][:service|port]
46 表示 IP 协议的版本(IPV4、IPV6)
protocol 表示网络协议的名称,比如 TCP 或 UDP
hostname 或 hostaddr 表示主机地址
service 指 /etc/services 中的名称,比如 smtp 或多个服务的列表
port 表示端口号,可以指定一个或多个

lsof命令常见用法举例:
(1)查看哪些进程打开了某个文件
如下查询打开了 /bin/bash 文件的进程,

[root@localhost ~]# lsof /bin/bash
COMMAND  PID USER  FD   TYPE DEVICE SIZE/OFF     NODE NAME
bash    1291 root txt    REG  253,0   964536 50336671 /usr/bin/bash
bash    1310 root txt    REG  253,0   964536 50336671 /usr/bin/bash

(2)查看哪些进程打开了某个目录以及目录下的文件
+d 选项不执行递归查询,如下
在这里插入图片描述
+D 选项会对指定的目录进行递归查询,如下:
在这里插入图片描述
在卸载文件系统时,如果有进程打开了该文件系统中的文件或目录,卸载操作就会失败。因此在卸载文件系统前最好通过 lsof +D 检查文件系统的挂载点,杀掉相关的进程然后再执行卸载操作。

(3)查看某个进程打开的所有文件
在这里插入图片描述
(4)组合多个选项查看
如果为 lsof 命令指定多个选项,这些选项间默认是或的关系,满足任何一个选项的结果都会被输出。可以添加额外的 -a 选项,它的作用就是让其它选项之间的关系变为与,比如下面的命令:

[root@localhost ~]# lsof -a -p $$ -d0,1,2
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    1310 root    0u   CHR  136,0      0t0    3 /dev/pts/0
bash    1310 root    1u   CHR  136,0      0t0    3 /dev/pts/0
bash    1310 root    2u   CHR  136,0      0t0    3 /dev/pts/0
-p选项指定当前进程的PID
-d 选项则用来指定进程打开的文件描述符(可以通过逗号分隔多个文件描述符)
-a 表示-p和-d同时满足的才输出

(5)通过指定程序的名称查看打开的文件
losf -c
在这里插入图片描述
(6)lsof -i 查看被打开的与网络相关的文件
-i 选项默认会同时输出 IPv4 和 IPv6 打开的文件
在这里插入图片描述
只列出IPv4 或 IPv6 打开的文件
在这里插入图片描述
列出与22号端口相关的文件
在这里插入图片描述
(7)统计系统打开的文件总数
在这里插入图片描述
命令中的 -P 选项表示不解析端口号,-n 选项表示不解析主机名,这两个选项主要的目的是为了提升 lsof 命令的执行速度。

5.管道中使用变量

管道是独立的进程,执行完即销毁,使用()或是while组合可以编写复杂的控制逻辑。
如下方式无法获取到变量x的值:

echo hello world | read x;echo $x

在管道中使用变量,如下方法可以获得变量x:
方法一:

echo hello world | (read x;echo $x;

方法二:

[root@localhost ~]# echo hello world | while read x; do
> echo $x;
> done
hello world

6.grep命令补充

grep -E pattern file 使用扩展正则表达式
grep pattern -r dir/ 递归搜索
grep -A -B -C pattern file 打印命中数据得上下文(-Bn 前n行,-An 后n行,-Cn 前n行+后n行)

7.BRE基本正则表达式

代码说明
^开头
$结尾
[a-z] [0-9]区间如果开头带有^表示不能匹配区间内得元素
*0个或多个
.表示任意字符(除换行符以外)

8.ERE扩展正则表达式

(1)ERE是在基本正则表达式(BRE)基础上的扩展,基本的扩展正则如下:

代码说明
非贪婪匹配(最多一次匹配,也就是0次或1次匹配)
+至少一次匹配(一次或多次匹配)
()用于分组,BRE中只将()当作普通字符对待,要使用此功能必须加\进行转义,即“\(\)”
{}范围约束,用于表示重复匹配的次数;BRE中只将{}当作普通字符对待,要使用此功能必须加\进行转义,即“\{\}”
|匹配多个表达式的任何一个

(2)grep、awk、sed开启ERE
grep:grep -E
在这里插入图片描述
awk: awk ‘/ /’
在这里插入图片描述
sed:sed -E

[root@localhost ~]# echo "test" | sed -E "s/t|s/2/g"
2e22  #开启了ERE,将t或s都换成了2

9.awk小技巧

(1)用awk命令查看第一行,用空格分隔的每列对应的$号,是$1还是KaTeX parse error: Expected '}', got 'EOF' at end of input: …+) print i" = "i}’ test.text
test.text文件内容如下:
在这里插入图片描述
执行命令后,返回如下:

1 = b2423534
2 = test02
3 = test03
4 = test04
5 = test05

二、Linux实战

1.查找有多少用户登录系统

w | awk '{print $1}' | sed 1,2d | sort | uniq -c | wc -l
w命令显示目前登入系统的用户信息,$1为用户名
awk '{print $1}'打印第一列用户名信息
sed 1,2d 删除1,2行title(1,2行不是用户信息)
sort 用sort排序
uniq -c 得到重复次数(筛选出重复登录的用户)
wc -l 显示行数,得到登录系统实际人数

2.找出所有404和500的错误日志,统计错误日志的行数

awk '$9~/404|500/{print $9}' test.log |wc -l
# test.log里每行按空格分割,$9是code字段,$9~/404|500/会在$9查405或500的都匹配出来

3.找出状态码为500错误的那条日志记录的前一行与后两行

less nginx.log | grep -E -B 1 -A 2 "HTTP\/1.1\" 500"

grep -B : 搜索到关键字后打印输出本行和前面行数
grep -A : 搜索到关键字后打印输出本行和后面行数
gerp -E : 正则匹配

找出访问量最高的url, 统计分析,取出top3

4.找出访问量最高的url, 统计分析,取出top3

test.log文件每行$7是url,命令如下:

awk '{print $7}' nginx.log| sort | uniq -c | sort -nr | head -3
# 用uniq -c 得到重复次数
#再用sort实现按次数倒叙排列
#head -3 得到出现频率最高的前三个url

5.找出 url为/topics 的平均响应时间,响应时间在倒数第二个字段

nginx.log里$7为url的位置,命令如下:

less nginx.log | awk '$7=="/topics"{total+=$(NF-1);count+=1}END{print total/count}'

6.找出访问量最高的页面地址,借助于sed的统计分析

其余规则:

  • /topics/16689/replies/124751/edit 把数字替换为 /topics/id/replies/id/edit
  • /_img/uploads/photo/2018/c54755ee-6bfd-489a-8a39-81a1d7551cbd.png!large 变成 /_img/uploads/photo/2018/id.png!large
  • /topics/9497 改成 /topics/id
  • url中的query可以去掉

输出要求如下:
url pattern对应的请求数量
取出top 10请求量的url pattern

命令:

awk '{print $7}' nginx.log | 
  sed -E \
    -e 's#/[0-9]*/[a-z0-9\-]*\.(png|gif|jpeg|jpg).*#/_id_/_id_.image#' \
    -e 's#[\?!].*##' \
    -e 's#/(topics|replies|avatar)/[0-9]{1,}#/\1/_id_#g' \
    -e 's#/[^/]*/(topics|followers|following|favorites|replies|columns|reward|calendar|people)#/_uid_/\1#' \
    -e 's#^/[^/]*$#/_top_#' \
    -e 's#/topics/node[0-9]*#/topics/node#' | 
  sort | uniq -c | sort -nr 

7.性能统计脚本

统计阿里云盾 AliYunDun 进程的cpu与mem,持续统计20s,每秒输出一下即时的cpu与mem的利用率,并在最后结束时候给出cpu与mem的平均值,输出结果的字段用tab隔开

top -b -d 1 -n 20 | grep --line-buffered -i aliyundun$ | awk 'BEGIN{OFS="\t";print "CPU", "MEM"}{cpu=$(NF-3);mem=$(NF-2);print cpu,mem;cpu_total+=cpu;mem_total+=mem;}END{print "\navg:" ;print cpu_total/NR, mem_total/NR}'
# -d 1表示每1s更新一次
#  -b:以批次的方式执行top
#  -n:与-b配合使用,表示需要进行几次top命令的输出结果;-n 20就是持续进行20次;

也可以用pid的方式:

top -b -p 2076 -n 20 -d 1 | grep 2076 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}END{print "------";print cpu/NR,mem/NR}'
#pid 为2076

8.网络连接数统计

统计每个端口对应的网络连接数,以及每个端口的不同状态的数量

netstat -tnp |sed 1,2d | awk '{print $4,$6}' | awk -F: '{print $2}' | sort | uniq -c | sort -nr
# netstat -tnp前面有2行不是网络数据,所以后面用sed 1,2d删除;
# $4为链接的ip:port,$6为状态,用awk '{print $4,$6}'取出
# 用冒号:分隔取出端口号和状态 awk -F: '{print $2}'
# 最后再通过排序去重,再倒序查看

输出如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值