AWK/SED

awk

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk '{pattern + action}' {filenames}

统计ip

cat test.txt | awk '{print $2}' | sort | uniq -c | sort -n -r | head -n 1

sed 编辑文本

sed -e 's/foo/bar/' myfile

将 myfile 文件中每行第一次出现的foo用字符串bar替换,然后将该文件内容输出到标准输出

sed -e 's/foo/bar/g' myfile

g 使得 sed 对文件中所有符合的字符串都被替换

sed -i 's/foo/bar/g' myfile

选项 i 使得 sed 修改文件

sed -i 's/foo/bar/g' ./m*

批量操作当前目录下以 m 开头的文件

sed -i 's/foo/bar/g' `grep foo -rl --include="m*" ./`

``括起来的grep命令,表示将grep命令的的结果作为操作文件

grep 命令中,选项r表示查找所有子目录,l表示仅列出符合条件的文件名,用来传给sed命令做操作,--include="m*" 表示仅查找 m 开头的文件

管道

管道是linux提供的一种常见的进程通信工具

管道中的数据只能读取一次

管道的实现并没有使用专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。通过将两个 file 结构指向同一个临时的 VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。

IO模型

mmap

零拷贝技术:让数据传输不需要经过user space 使用mmap

mmap系统调用导致文件的内容通过DMA模块被复制到内核缓冲区中,该缓冲区之后与用户进程共享,这样就内核缓冲区与用户缓冲区之间的复制就不会发生。

sendfile

ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

参数特别注意的是:in_fd必须是一个支持mmap函数的文件描述符,也就是说必须指向真实文件,不能使用socket描述符和管道。

out_fd必须是一个socket描述符。

由此可见sendfile几乎是专门为在网络上传输文件而设计的。

Sendfile 函数在两个文件描述符之间直接传递数据(完全在内核中操作,传送),从而避免了内核缓冲区数据和用户缓冲区数据之间的拷贝,操作效率很高,被称之为零拷贝。

select poll(NIO)

select poll epoll都是IO多路复用的实现方式!

select系统调用的目的是:在一段指定时间内,监听用户感兴趣的文件描述符上的可读、可写和异常(异常不包括网络断开)事件。poll和select应该被归类为这样的系统调用,它们可以阻塞地同时探测一组支持非阻塞的IO设备,直至某一个设备触发了事件或者超过了指定的等待时间——也就是说它们的职责不是做IO,而是帮助调用者寻找当前就绪的设备

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

fd_set结构体是文件描述符集,该结构体实际上是一个整型数组,数组中的每个元素的每一位标记一个文件描述符。fd_set能容纳的文件描述符数量由FD_SETSIZE指定,一般情况下,FD_SETSIZE等于1024,这就限制了select能同时处理的文件描述符的总量。

1)nfds参数指定被监听的文件描述符的总数。通常被设置为select监听的所有文件描述符中最大值加1;

2)readfds、writefds、exceptfds分别指向可读、可写和异常等事件对应的文件描述符集合。这三个参数都是传入传出型参数,指的是在调用select之前,用户把关心的可读、可写、或异常的文件描述符通过FD_SET函数分别添加进readfds、writefds、exceptfds文件描述符集,select将对这些文件描述符集中的文件描述符进行监听,如果有就绪文件描述符,select会重置readfds、writefds、exceptfds文件描述符集来通知应用程序哪些文件描述符就绪。这个特性将导致select函数返回后,再次调用select之前,必须重置我们关心的文件描述符,也就是三个文件描述符集已经不是我们之前传入 的了。

3)timeout参数用来指定select函数的超时时间。

1)如果指定timeout为NULL,select会永远等待下去,直到有一个文件描述符就绪,select返回;

2)如果timeout的指定时间为0,select根本不等待,立即返回;

3)如果指定一段固定时间,则在这一段时间内,如果有指定的文件描述符就绪,select函数返回,如果超过指定时间,select同样返回。

select的几大缺点:

1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大

2)每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大(不适合服务器,但客户端也可以使用)

3)select支持的文件描述符数量太小了,默认是1024

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

与select非常类似,poll比select的好处就是没有描述符数量限制,select 有1024 的限制,描述符不能超过此值,poll不受限制。

此函数在系统调用select内部被使用,作用是把当前的文件指针挂到设备内部定义的等待

队列中。

send不是立即发送数据,而是将数据放在本地网卡缓冲区中。

epoll(NIO)

select,poll还是在应用中轮询Socket,容易浪费;OS会自动轮询,通过epoll_wait返回。

epoll 与select和poll在使用和实现上有很大区别。首先,epoll使用一组函数来完成,而不是单独的一个函数;其次,epoll把用户关心的文件描述符上的事件放在内核里的一个事件表中,无须向select和poll那样每次调用都要重复传入文件描述符集合事件集。

系统调用:

epoll_create 创建一个epoll对象,一般epollfd = epoll_create()

epoll_ctl (epoll_add/epoll_del的合体),往epoll对象中增加/删除某一个流的某一个事件

比如

epoll_ctl(epollfd, EPOLL_CTL_ADD, socket, EPOLLIN);//注册缓冲区非空事件,即有数据流入

epoll_ctl(epollfd, EPOLL_CTL_DEL, socket, EPOLLOUT);//注册缓冲区非满事件,即流可以被写入

epoll_wait(epollfd,...)等待直到注册的事件发生

(注:当对一个非阻塞流的读写发生缓冲区满或缓冲区空,write/read会返回-1,并设置errno=EAGAIN。而epoll只关心缓冲区非满和缓冲区非空事件)。

对于第一个缺点,epoll的解决方案在epoll_ctl函数中。每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD),会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。

对于第二个缺点,epoll的解决方案不像select或poll一样每次都把current轮流加入fd对应的设备等待队列中,而只在epoll_ctl时把current挂一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd(利用schedule_timeout()实现睡一会,判断一会的效果,和select实现中的第7步是类似的)。

对于第三个缺点,epoll没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。

总结:

1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。

2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。

epoll原理

  1. epoll初始化时,会向内核注册一个文件系统,用于存储被监控的句柄文件,调用epoll_create时,会在这个文件系统中创建一个file节点。同时epoll会开辟自己的内核高速缓存区,以红黑树的结构保存句柄,以支持快速的查找、插入、删除。还会再建立一个list链表,用于存储准备就绪的事件。
  2. 当执行epoll_ctl时,除了把socket句柄放到epoll文件系统里file对象对应的红黑树上之外,还会给内核中断处理程序注册一个回调函数,告诉内核,如果这个句柄的中断到了,就把它放到准备就绪list链表里。所以,当一个socket上有数据到了,内核在把网卡上的数据copy到内核中后,就把socket插入到就绪链表里。
  3. 当epoll_wait调用时,仅仅观察就绪链表里有没有数据,如果有数据就返回,否则就sleep,超时时立刻返回。

边缘触发模式ET(Edge_triggered)和水平触发模式LT(Level_triggered)

Level_triggered(水平触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在上没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果系统中有大量你不需要读写的就绪文件描述符,而它们每次都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率!!!

Edge_triggered(边缘触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符!!!

IOCP(AIO)

微软在 Winsocket2 中引入了 IOCP(Input/Output Completion Port)模型。IOCP 是 Input/Output Completion Port(I/O 完成端口)的简称。简单的说,IOCP 是一种高性能的 I/O 模型,是一种应用程序使用线程池处理异步 I/O 请求的机制。Java7 中对 IOCP 有了很好的封装,程序员可以非常方便的时候经过封装的 channel 类来读写和传输数据。

不仅和epoll一样接收到Socket的事件,并且接收时OS已经完成了IO,不需要在应用层进行IO。

首先我们创建一个完成端口 CreateIOCompletionPort,然后再创建一个或多个工作线程,并指定它们到这个完成端口上去读取数据。再将远程连接的套接字句柄关联到这个完成端口。工作线程调用 getQueuedCompletionStatus 方法在关联到这个完成端口上的所有套接字上等待 I/O 的完成,再判断完成了什么类型的 I/O,然后接着发出 WSASend 和 WSARecv,并继续下一次循环阻塞在 getQueuedCompletionStatus。

具体的说,一个完成端口大概的处理流程包括:

创建一个完成端口;

Port port = createIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, fixedThreadCount());

创建一个线程 ThreadA;

ThreadA 线程循环调用 GetQueuedCompletionStatus 方法来得到 I/O 操作结果,这个方法是一个阻塞方法;

While(true){

getQueuedCompletionStatus(port, ioResult);

}

主线程循环调用 accept 等待客户端连接上来;

主线程 accept 返回新连接建立以后,把这个新的套接字句柄用 CreateIoCompletionPort 关联到完成端口,然后发出一个异步的 Read 或者 Write 调用,因为是异步函数,Read/Write 会马上返回,实际的发送或者接收数据的操作由操作系统去做。

if (handle != 0L) {

createIoCompletionPort(handle, port, key, 0);

}

主线程继续下一次循环,阻塞在 accept 这里等待客户端连接。

操作系统完成 Read 或者 Write 的操作,把结果发到完成端口。

ThreadA 线程里的 GetQueuedCompletionStatus() 马上返回,并从完成端口取得刚完成的 Read/Write 的结果。

在 ThreadA 线程里对这些数据进行处理 ( 如果处理过程很耗时,需要新开线程处理 ),然后接着发出 Read/Write,并继续下一次循环阻塞在 GetQueuedCompletionStatus() 这里。

分区

磁盘的文件名

Linux 中每个硬件都被当做一个文件。

常见磁盘的文件名:

SCSI/SATA/USB 磁盘:/dev/sd[a-p]

IDE 磁盘:/dev/hd[a-d]

其中文件名后面的序号的确定与磁盘插入的顺序有关,而与磁盘所插入的插槽位置无关。

Linux系统使用字母和数字的组合来指代硬盘分区,Linux系统使用一种更加灵活的命名方案,该命名方案是基于文件的,文件名的格式为/dev/xxyN,

/dev/:这是Linux系统下所有设备文件所在的目录名。

xx:分区名的前两个字母表示分区所在设备的类型,通常是hd(IDE硬盘)或sd(SCSI硬盘)。

y:这个字母表示分区所在的设备。

N:最后的数字N代表分区。

挂载目录:

Linux系统处理分区及磁盘存储的方法与Windows截然不同,Linux系统中的每一个分区都是构成支持一组文件和目录所必需的存储区的一部分。它是通过挂载来实现的,挂载是将分区关联到某一目录的过程,挂载分区使起始于这个指定目录(通称为挂载目录)的存储区能够被使用。

分区表

磁盘分区表主要有两种格式,一种是限制较多的 MBR 分区表,一种是较新且限制较少的 GPT 分区表。

1. MBR

MBR 中,第一个扇区最重要,里面有:主要开机记录(Master boot record, MBR)及分区表(partition table),其中 MBR 占 446 bytes,partition table 占 64 bytes。

分区表只有 64 bytes,最多只能存储 4 个分区,这 4 个分区为主分区(Primary)和扩展分区(Extended)。其中扩展分区只有一个,它将其它空间用来记录分区表,可以记录更多的分区,因此通过扩展分区可以分出更多区分,这些分区称为逻辑分区。

Linux 也把分区当成文件,分区文件的命名方式为:磁盘文件名+编号,例如 /dev/sda1。注意,逻辑分区的编号从 5 开始。

2. GPT

不同的磁盘有不同的扇区大小,例如 512bytes 和最新磁盘的 4k。GPT 为了兼容所有磁盘,在定义扇区上使用逻辑区块地址(Logical Block Address, LBA)。

GPT 第 1 个区块记录了 MBR,紧接着是 33 个区块记录分区信息,并把最后的 33 个区块用于对分区信息进行备份。

压缩

tar [主选项+辅选项][文件或者目录]

备份/root/abc目录及其子目录下的全部文件,备份文件名为abc.tar。

[root@PC-LINUX ~]# touch /root/abc/a /root/abc/b /root/abc/c

//在/root/abc目录中创建/root/abc/a、/root/abc/b和/root/abc/c文件

[root@PC-LINUX ~]# tar cvf abc.tar /root/abc

查看abc.tar备份文件的内容,并显示在显示器上。

[root@PC-LINUX ~]# tar tvf abc.tar

将文件/root/abc/d添加到abc.tar包里面去。

[root@PC-LINUX ~]# touch /root/abc/d

[root@PC-LINUX ~]# tar rvf abc.tar /root/abc/d

更新原来tar包abc.tar中的文件/root/abc/d。

[root@PC-LINUX ~]# tar uvf abc.tar /root/abc/d

tar调用gzip

把/root/abc目录包括其子目录全部做备份文件,并进行压缩,文件名abc.tar.gz。

[root@PC-LINUX ~]# tar zcvf abc.tar.gz /root/abc

查看压缩文件abc.tar.gz的内容,并显示在显示器上。

[root@PC-LINUX ~]# tar ztvf abc.tar.gz

将压缩文件abc.tar.gz解压缩出来。

[root@PC-LINUX ~]# tar zxvf abc.tar.gz

tar调用bzip2

将目录/root/abc及该目录所有文件压缩成abc.tar.bz2文件。

[root@PC-LINUX ~]# tar cjf abc.tar.bz2 /root/abc

查看压缩文件abc.tar.bz2的内容,并显示在显示器上。

[root@PC-LINUX ~]# tar tjf abc.tar.bz2

将abc.tar.bz2文件解压缩。

[root@PC-LINUX ~]# tar xjf abc.tar.bz2

Linux必懂知识大总结(下)相关推荐

  1. Linux必懂知识大总结(上)

    CPU top top:查看每个进程的情况 在top模式下,输入1:查看每个CPU的性能数据,注意观察是否有CPU100%占用率 CPU参数含义: 1)us过高表示Java应用程序消耗了大量CPU,需 ...

  2. 嵌入式linux 必懂概念科普篇

    嵌入式linux 必学基础知识 应用编程概念 系统调用是什么? 应用编程.裸机编程.驱动编程概念 文件 I/O 操作 文件i/o的系统调用函数 文件管理 文件描述符的由来 什么是空洞文件? 原子操作与 ...

  3. Linux内核必懂知识—调度器分析及完全公平调度器CFS

    调度器分析 调度器 内核中安排进程执行的模块,用以切换进程状态. 做两件事:选择某些就绪进程来执行:打断某些执行的进程让其变为就绪状态. 分配CPU时间的基本依据:进程优先级. 上下文切换(conte ...

  4. 2018年Fintech金融科技关键词和入行互金从业必懂知识

    2018年过去大半,诸多关键词进入眼帘: 5G,消费降级,数据裸奔,新零售,AI,物联网,云计算,合规监管,风控,割韭菜,区块链,生物识别,国民空闲时间以及金融科技. 这些词充斥着我们的生活和时间,而 ...

  5. elxel表格纸张尺寸_印刷设计必懂知识:印刷纸张类型介绍

    纸引未来网,造纸印刷包装行业人聚集地,有纸张价格指数,求购彩盒.纸张订单信息 纸引未来网讯 关于印刷纸张种类主要按纸张包装形式划分和用途划分,介绍了常见的11种印刷纸张类型,这将是一个系列的印刷设计知 ...

  6. 今日头条推广入门必懂知识简介

    尽管今日头条推广效果不错,但我发现很多广告主对其仍然不是很了解.为此,我以自己的操作经验出发,以帮助大家进一步了解今日头条推广. 今日头条简介: 今日头条创建于2012年,是目前国内移动互联网领域成长 ...

  7. 印刷设计必懂知识04:印刷分辨率介绍

    内容提要:本文详尽的为大家展现了印刷分辨率相关的知识.包含印刷分辨率多少合适,ps印刷分辨率如何设置都有所介绍到.对PS感兴趣的朋友可加ps学习交流群:142574315(www.itblw.com) ...

  8. java零基础入门必懂知识

    读输入 应声虫(你输啥 它回答啥) import java.util.Scanner; public class Main{ public static void main(String[] args ...

  9. Linux必学知识(超全)

    Linux 一.Linux 的介绍 二.CentOS 安装技术难点-网络配置三种方式理解 2.1虚拟机的三种网络配置方式的说明 2.2 Centos 终端的使用和联网 2.2.1在 centos 的 ...

最新文章

  1. 我有一个计划001之数据挖掘面试(更新ing)
  2. Hyperledger Fabric 区块数据结构(1)Block
  3. JAVA基础知识(2)--队列的操作
  4. 面向对象设计思想-C语言
  5. awk教程入门与实例练习(二)
  6. 一维数组转化为二维数组(java)
  7. python通过解释器来编译_python 解释器与编译过程,代码的搬运工
  8. lunix入侵别人电脑_记录一次Linux的实战入侵过程
  9. 候选公示!高工智能汽车金球奖第二批入围年度产品/方案亮相
  10. android表情选择器,android 新浪微博客户端的表情功能的实现
  11. c语言自学书籍 新闻,如何学习C语言
  12. Win11 Android Stuido虚拟机启动失败、崩溃
  13. 解决mininet运行报错“ImportError: No module named mininet.log”
  14. egde被360导航劫持
  15. Python模块之snmp-cmds,easysnmp
  16. 计算机excel界面,2017《职称计算机》知识点:Excel用户界面
  17. Freedom and discipline
  18. 明日边缘:愈演愈烈的POS机网络犯罪
  19. 正则表达式(详细解析)
  20. python文件处理相关

热门文章

  1. 深入浅出FSUIPC的作用以及使用方法
  2. 两个结构体ifconf和ifreq
  3. [vc]如何对radio按钮分组
  4. 预处理命令中的#和##
  5. vxworks 调式
  6. java 参数 string_java(String和StringBuffer分别作为参数传递)
  7. 锐炬显卡可以linux吗,Intel Broadwell桌面CPU性能测试:Iris Pro 6200核显无敌了
  8. 神经网络与深度学习——TensorFlow2.0实战(笔记)(五)(NumPy科学计算库<1>python)
  9. 4.Dynamics CRM 数据数量限制更改
  10. [你必须知道的.NET] 第二回:对抽象编程:接口和抽象类