进程
如何查看当前有多少个进程?
ps:查看当前进程
ps -ef: 会列举出所有的进程
ps -ef | less查看一个进程的状态, 可以看到用户的 UID,进程的 PID,父进程的PPID,以及进程开始的时间,运行参数等信息。
top:当执行 top后,我们可以看到动态的交互界面上显示了整个机器的一个状态,包括了负载情况,当前用户,启动时间,相关的任务树,以及内存,进程的一些数据等,同样也包含 PID、USER、内存、共享内存,CPU 占比等全部信息。还可以对进程进行排序和查询,所以top 是一个非常实用的查看进程的命令,如果某台机器出现问题时,第一个输入的命令通常就是 top,查看哪个进程内存、CPU 占比高来排查问题原因。
网络
最后,我们来学习网络,当一个文件加载到 CPU 中被执行的过程中它就变成了一个进程,有的时候进程之间需要通信,这个时候就会开启一个 socket,socket 就是对外建立连接的一个窗口,然后借助 TCP 协议进行通信。但进行通信之前首先需要进程开启一个端口,那我们如何查看本地开启了多少端口?这些端口又是由哪些进程开启的呢?
netstat -tlnp
- -t 指的是 TCP 协议
- -l (listen)指哪几个进程开启了对外的链接,负责监听端口
- -n 指不需要解析远程服务器的名字,以加快运行速度
- -p 指打印进程
- 看到当前机器的第一条端口信息开放了 22 端口,这时我就可以通过 ssh 登录这个服务器,如果系统没有开放任何端口,外部是无法进行任何操作的,也就是此时机器对外是完全封闭的。
- 第二条端口信息,开放了 25 端口并监听到了 127.0.0.1,监听到的这个端口外部是访问不了的,只用于本地进程间进行通信。
netstat -tnp
l 是 listen,监听的意思,它可以列举目前在当前机器上有多少进程在与外部进行通信,那如果我们去掉 l 直接使用 netstat -tnp 命令会怎么样?
- 第一条信息,表示访问了一个远程服务器的 80 端口
- 第二条信息,本地某个进程在访问外部服务
- 第四条信息是本地与远程的 3128 建立起一个链接。
通过 netstat -tnp 获取了本地机器上有多少个链接正在与外部进行通信,属于哪个进程你也可以看到。
Linux三剑客
- grep: 根据正则表达式查找相关内容并打印对应的数据
- awk: 可以根据定位到的数据行处理其中的分段
- sed:是stream editor流式编辑器的简称,可以定位到数据行并对数据进行增删改查操作。
因为它们三个组合使用的功能非常的强大,几乎完美的应对了 Shell 中的数据分析场景,于是人们把这三个工具统称为 Linux 三剑客。
通过对三剑客与 SQL 进行类比,来具体看看它们到底能做些什么?
- grep 相当于 SQL 的 select *from table,它可以进行数据的查找与定位
- awk 相当于 SQL 的 select field from table,它可以进行数据切片
- sed 相当于 SQL 的 update table set field=new where field=old,它可以对数据进行修改
- grep 和 awk 可以进行组合使用,来达到查找数据并对数据进行分割的目的
- grep 也可以与 sed 组合使用,达到查找数据并修改的目的
- 它们三个还可以组合在一起使用来完成一系列的操作,就相当于大数据处理中的 Map-Reduce
grep
grep hello test.txt: 把所有包含hello的行全找出来了
grep "[st].." test.txt 使用正则表达式获取以字母 s 或 t 开头的后面跟任意两个字符的数据
grep -o "[st].." test.txt:只打印匹配的内容,而不是整条数据。
grep -i "HELLO" test.txt 可以忽略字符的大小写。
grep -v "[st].." test.txt: 只显示了一条数据,过滤掉了匹配正则条件的内容。
-E 表示支持使用扩展正则表达式,我们接下来详细了解下 pattern 正则表达式。
正则表达式分为两类,一类是基本表达式,第二类是基本表达式。
基本表达式 | 扩展表达式 |
^:表示开头 | ? 表示非贪婪匹配 |
$:表示结尾 | +表示一个或多个 |
*:表示0个或者多个 | ()表示分组 |
[]表示匹配任意项 | {}表示一个范围的约束 |
.表示匹配任意字符 | |表示匹配多个表达式中的任何一个 |
grep -E "(hog|home)" test.txt:结果输出了分别匹配hog与home
但是如果指令中不包含-E,则指令不支持扩展正则,这个时候就会发现什么都匹配不到,但是不使用-E, 我们可以使用\转义符对匹配条件进行转义,也可以达到同样的效果。
grep "\(hog\|home\)" test.txt
awk
awk 是 Linux 下的一个命令,同时也是一种语言解析引擎,它的功能非常强大,具备完整的编程特性,可以执行命令、进行网络请求等操作.
(1)代替grep
awk "pattern{action}" pattern是匹配条件, action表示具体需要做的处理。 pattern语法在一定程度上可以代替grep
awk "/[st]../" test.txt: 使用双/表示一个正则匹配,和grep一样,轻松地打印出匹配到的内容,但它没有使用grep简洁。
(2)区间选择: 在1,2,3之间,使用awk‘$0>2’指令打印大于2的数据3
(3)awk 几个标准的内置变量
- 1. NR代表记录数 awk 'NR>1' test.txt:打印去掉第一行的数据。
- 2. 其他内置变量
- FS 表示字段分隔符
- OFS 表示输出数据的字段分隔符
- RS 表示记录分隔符
- ORS 表示输出字段的行分隔符
- NF 表示字段数
- NR 表示记录数
awk '{print NR, NF}' test.txt: 分别打印出了每行有几个字段
awk -Fo '{print NR,NF}' test.txt: 输出显示我们以o为分隔符,将每行记录分为了几个字段
还可以使用 BEGIN 指令,能够得到同样的结果。
awk 'BEGIN{FS="t"}{print NR, NF, $1, $2}' test.txt 会根据默认的分隔符打印出每个字段的具体内容。
假设我们以 t 为分隔符打印 $1 和 $2,我们来分析下结果
awk 'OFS="-"{print $1, $2, $3}' test.txt: hello 指定为 $1,from 指定为 $2,并将默认的空格分隔符替换为 -,我们可以通过 $ 获取具体字段并对其进行相关操作
(4) 利用awk实现简单的数据计算功能
awk 'BEGIN{print 10000/3}'
(5) awk 还支持词典,用来统计一些特征和数据,它类似于 Java 的 hash 和 Python 的字典
sed
sed 的语法和 awk 有点类似,只不过具体的用法不太一样。
- sed[addr]X[opptions],其中 [] 定义了一个范围,x位是具体操作,options表示进行数据修改的选项。
- -e 表示可以指定表达式。
- sed -n '2p' 2 表示打印第二行的数据。
- s 表示查找并替换。
- -i 表示直接修改源文件
- -E 支持扩展表达式。
sed 's#testerhom#world#' test.txt: 其中 s 后面可以跟任意符号,比如 / 或 # 都可以表示分隔符,它会用后面的内容替换前面的内容。
sed 's/t../xxx/' test.txt:表示把t开头的都换成xxx
可以看到,后面的 ter 没有改变,是因为需要添加一个额外的标记符 /g。sed 's/t../xxx/g' test.txt
/g 表示除了替换第一个匹配的字符以外还会把第二个也替换掉,这就是 sed 的用法
- 那么关于它的匹配符 pattern,你可以给定具体的行数也可以通过正则匹配一个范围,在某个范围内做一个修改;
- 区间范围也是一个类似的用法,你会发现它和 awk 语法很像。
- action 与 awk 的不同点在于 awk 专注于数据的提取,而 sed 更专注于数据的修改,sed 的重要作用是完成对数据的增删改查工作,比如:
-
d 是删除
-
p 是打印
-
s 是查找并进行替换
-
\1 \2 可以根据匹配的数据进行分组处理
-
文件描述符
- Shell 下任何程序都有输入和输出,这里需要额外注意的是错误输出.
- 而输入是一个读取文件的过程,比如我们输入 grep "hogwarts" /tmp/hello.txt 指令便是从 hello.txt 文件中读取 hogwarts。
但如果我们不传递给指令一个文件,会发生什么样的效果?
- 比如输入 grep "hogwarts" 指令,你会发现什么都没有显示,继续输入 xxx、dddd 仍没有任何反应,直到输入 hogwarts 时,系统才会输出 hogwarts.
- 我们看到如果不传递输入文件,grep 会默认从当前输入读取内容。
管道
用 | 表示,它可以将上一个指令的输出自动变成下一个指令的输入
- 输入文件就是标准输入 0,如果当没有输入文件时会获取当前输入窗口中的数据,读到数据后可以对数据进行一系列的操作
- 标准输出 1 就是一个输出文件,
- 如果错误输出文件就是标准错误 2。
输入 echo hello hogwarts | gerp hogwarts 指令,你会看到输出了正确的内容。因为上一个命令输入了 hello hogwarts,再经 grep 后输出。
再举个例子
首先通过 cat test.txt 指令打印test.txt 文件。
然后通过管道打印包含 testerhome 的信息行。cat test.txt | grep testerhome
如果此时我们只想得到 testerhome 这个单词怎么办呢?
cat test.txt | grep testerhome | awk '{print $3}',因为 hello from testerhome 是以空格隔开的,所以指令中的 $3 表示第三个元素。
我们再继续使用管道将 testerhome 中的 tester 替换成 dev,输入 cat test.txt | grep testerhome | awk '{print $3}' | sed 's#tester#dev#' 指令,就可以看到 testerhome 就变成了devhome 了。