Linux入门(二)

计算机原理系列

欢迎大家关注「海拉鲁知识大陆」 多交流不迷路

Linux入门(二)

在上一章Linux入门(一)中rm -rf /是比较简单的哈,那么升级一下:xargs指令的作用是啥呢?

1.进程

应用的可执行文件是放在文件系统里,把可执行文件启动就会在操作系统里(具体来说就是在内存中)形成一个应用的副本,这个副本就是一个进程。

那进程就是应用的执行副本,进程也是操作系统分配资源的最小单位(前者是定义,后者是作用。)。

ps

如果你要看进程的情况,可以用ps指令。p代表processes,也就是进程;s代表snapshot,也就是快照。

当然操作系统也不可能只有这么几个进程,这是因为不带任何参数的ps指令显示的是同一个电传打字机(TTY上)的进程。TTY这个概念是一个历史的概念哈,用来传递信息,现在已经被传真、邮件、微信等取代。

操作系统上的TTY是一个输入输出终端的概念,比如用户打开bash,操作系统就为用户分配了一个输入输出终端。没有加任何参数的ps只显示在同一个TTY的进程。

如果想看到所有的进程,可以用ps -e,-e没有特殊含义,只是为了和-A区分开。我们通常不直接用ps -e而是用ps -ef,这是因为-f可以带上更多的描述字段,如下图所示:

  • UID指进程的所有者;
  • PID是进程的唯一标识;
  • PPID是进程的父进程ID;
  • C是CPU的使用率;
  • STIME是开始时间;
  • TTY是进程所在的TTY,如果没有TTY就是?号;
  • TIME;
  • CMD是进程启动时的命令,如果不是一个Shell命令,而是用方括号括起来就是系统进程或者内核过程。

另外一个用得比较多的是ps aux,它和ps -ef差不多,感兴趣可以自己了解下具体含义。

top

还有一个和ps能力差不多,是显示的是实时更新数据的top指令。因为top显示的内容有点少, 我用的比较多的是htop的指令。

2.管道(Pipeline)

下面我们来聊聊管道,管道(Pipeline)的作用是在命令和命令之间,传递数据。比如说一个命令的结果,就可以作为另一个命令的输入。

输入输出流

每个进程拥有自己的标准输入流、标准输出流、标准错误流。

这几个标准流说起来有点复杂,但你可以理解都是文件。

  • 标准输入流(用 0 表示)可以作为进程执行的上下文(进程执行可以从输入流中获取数据)。
  • 标准输出流(用 1 表示)中写入的结果会被打印到屏幕上。
  • 如果进程在执行过程中发生异常,那么异常信息会被记录到标准错误流(用 2 表示)中。

重定向

我们执行一个指令,比如ls -l,结果会写入标准输出流,进而被打印。这时可以用重定向符将结果重定向到一个文件,比如说ls -l > out,这样out文件就会有ls -l的结果;而屏幕上也不会再打印ls -l的结果。

具体来说>符号叫作覆盖重定向;>>叫作追加重定向。>每次都会把目标文件覆盖,>>会在目标文件中追加。比如你每次启动一个程序日志都写入/var/log/somelogfile中,可以这样操作,如下:

powershell 复制代码
start.sh >> /var/log/somelogfile

经过这样的操作后,每次执行程序日志就不会被覆盖了。

另外还有一种情况,比如我们输入:

powershell 复制代码
ls1 > out

结果并不会存入out文件,因为ls1指令是不存在的。结果会输出到标准错误流中,仍然在屏幕上。这里我们可以把标准错误流也重定向到标准输出流,然后再重定向到文件。

powershell 复制代码
ls1 &> out

这个写法等价于:

powershell 复制代码
ls1 > out 2>&1

相当于把ls1的标准输出流重定向到out,因为ls1 > out出错了,所以标准错误流被定向到了标准输出流。&代表一种引用关系,具体代表的是ls1 >out的标准输出流。

管道的作用和分类

有了进程和重定向的知识,我们再梳理下管道的作用。管道(Pipeline)将一个进程的输出流定向到另一个进程的输入流,就像水管一样,作用就是把这两个文件接起来。如果一个进程输出了一个字符X,那么另一个进程就会获得X这个输入。

管道和重定向很像,但是管道是一个连接一个进行计算,重定向是将一个文件的内容定向到另一个文件,所以这二者经常会结合使用。

Linux 中的管道也是文件,有两种类型的管道:

  • 匿名管道(Unnamed Pipeline),这种管道也在文件系统中,但是它只是一个存储节点,不属于任何一个目录。说白了就是没有路径。
  • 命名管道(Named Pipeline),这种管道就是一个文件,有自己的路径。

FIFO

管道具有FIFO(First In First Out),FIFO和排队场景一样,先排到的先获得。所以先流入管道文件的数据,也会先流出去传递给管道下游的进程。

3.使用场景分析

接下来我们聊聊几个管道场景

排序

比如我们用ls,希望按照文件名排序倒序,可以使用匿名管道,将ls的结果传递给sort指令去排序。你看,这样ls的开发者就不用关心排序问题了。

去重

另一个比较常见的场景是去重,比如有一个字典文件,里面都是词语。

如果我们想要去重可以使用uniq指令,uniq指令能够找到文件中相邻的重复行,然后去重如下。

筛选

有时候我们想根据正则模式筛选对应的内容。比如说我们想找到项目文件下所有文件名中含有jmeter的文件。就可以利用grep指令,操作如下:

powershell 复制代码
find ./ | grep jmeter

find ./递归列出当前目录下所有目录中的文件。grep从find的输出流中找出含有jmeter关键字的行。

如果我们希望包含jmeter但不包含jar就可以这样操作:

powershell 复制代码
find ./ | grep jmeter| grep -v jar

grep -v就是匹配不包含 jar的结果。

数行数

还有一个比较常见的场景是数行数。比如一个log文件想知道里面有多少行,就可以使用wc -l指令,如下:

但是如果你想知道当前目录下有多少个文件,可以用ls| wc -l,如下:

中间结果

管道一个接着一个,是一个计算逻辑。有时候我们想要把中间的结果保存下来,这就需要用到tee指令。tee指令从标准输入流中读取数据到标准输出流。

tee还有一个能力,就是自己利用这个过程把输入流中读取到的数据存到文件中。比如下面这条指令:

powershell 复制代码
find ./ -i "*.log" | tee testA | grep jmeter

这句指令的意思是从当前目录中找到所有含有 jmeter关键字的log文件。tee本身不影响指令的执行,但是tee会把find指令的结果保存到testA文件中。

tee这个执行就类似英文字母"T"一样,连通管道两端,下面又开了口。这个开口,在函数式编程里面就叫副作用。

xargs

最后我们来看看初中难度的xargs指令。

xargs指令从标准数据流中构造并执行一行行的指令。xargs从输入流获取字符串,然后利用空白、换行符等切割字符串,在这些字符串的基础上构造指令,最后一行行执行这些指令。

假如我们重命名当前目录下的所有的文件,想在这些文件前面加一个前缀prefix_。比如说x.a文件需要重命名成prefix_x.a,我们就可以用xargs指令构造模块化的指令。

现在有如下图所示:

然后使用下图中的指令构造我们需要的指令:

  • 我们用ls找到所有的文件;
  • -I参数是查找替换符,这里我们用GG替代ls找到的结果;-I GG后面的字符串GG会被替换为x.a、x.b或x.z;
  • echo是一个在命令行打印字符串的指令。使用echo主要是为了安全,帮助我们检查指令是否有错误。

我们用xargs构造了7条指令。

管道文件

上面我们花了较长的一段时间聊了匿名管道,用|就可以创造和使用。匿名管道也是利用了文件系统的能力,是一种文件结构。其实匿名管道是有一个inode,但不属于任何一个文件夹。

还有一种管道叫作命名管道(Named Pipeline)。命名管道是要挂到文件夹中的,所以需要创建。用mkfifo指令可以创建一个命名管道,下面我们来创建一个叫作pipe1的命名管道,如下图所示:

命名管道和匿名管道能力类似,但可以连接一个输出流到另一个输入流。

如果这时cat pipe1的时候,可以发现当前的终端处于等待状态。因为cat pipe1的时候pipe1中没有内容。

比如这个时候我们再找一个终端去写一点东西到pipe中,比如说:

powershell 复制代码
echo "XXX" > pipe1

这个时候,cat pipe1就会返回,并打印出xxx,如下所示:

可以看到在cat pipe1后面增加了一个&符号。这个&符号代表指令在后台执行,不会阻塞我们继续输入。然后echo指令往pipe1中写入东西就会看到xxx被打印出来。

4.写在最后

现在最开始的题目:xargs指令的作用是啥?

【解析】 xargs 将标准输入流中的字符串分割成一条条子字符串,然后再按照我们自己想要的方式构建成一条条指令,拓展了Linux指令的能力。

比如我们可以用来按照某种特定的方式逐个处理一个目录下所有的文件;例如弱网测试中需要根据一个IP地址列表逐个ping这些IP,收集到每个IP地址的延迟。

相关推荐
虚伪的空想家11 分钟前
arm架构服务器使用kvm创建虚机报错,romfile “efi-virtio.rom“ is empty
linux·运维·服务器·javascript·arm开发·云原生·kvm
守城小轩12 分钟前
Chromium 140 编译指南 macOS 篇:基础环境准备(一)
chrome·macos·chrome devtools·指纹浏览器·浏览器开发·超级浏览器
火车头-11024 分钟前
【docker 部署nacos1.4.7】
运维·docker·容器
深藏bIue25 分钟前
linux服务器mysql目录下的binlog文件删除
linux·服务器·mysql
虾..41 分钟前
Linux 进程状态
linux·运维·服务器
测试者家园43 分钟前
DevOps 到底改变了测试什么?
运维·自动化测试·软件测试·devops·持续测试·智能化测试·软件测试和开发
扛枪的书生2 小时前
Linux 通用软件包 AppImage 打包详解
linux
只想安静的写会代码2 小时前
网卡信息查询、配置、常见故障排查
linux·服务器·windows
jiayong232 小时前
多子系统架构下的Nginx部署策略与最佳实践
运维·nginx·系统架构
皮糖小王子2 小时前
Docker打开本地镜像
运维·docker·容器