《拉钩课程 - 重学操作系统 - Linux 指令入门》
1、进程是什么?进程是应用的执行副本。应用的可执行文件是放在文件系统里,把可执行文件启动,就会在操作系统里(具体来说是内存中)形成一个应用的副本,这个副本就是进程。
2、Linux 管道(Pipeline)的作用是在命令和命令之间,传递数据。比如说一个命令的结果,就可以作为另一个命令的输入。这里说的命令就是进程。更准确地说,管道在进程间传递数据。
3、每个进程拥有自己的标准输入流、标准输出流、标准错误流。
- 标准输入流(用 0 表示)可以作为进程执行的上下文(进程执行可以从输入流中获取数据)。
- 标准输出流(用 1 表示)中写入的结果会被打印到屏幕上。
- 如果进程在执行过程中发生异常,那么异常信息会被记录到标准错误流(用 2 表示)中。
4、重定向:具体来说 >
符号叫作覆盖重定向;>>
叫作追加重定向。>
每次都会把目标文件覆盖,>>
会在目标文件中追加(ls -l > out
)。另外一种情况,可以把标准错误流重定向到标准输出流,然后再重定向到文件(ls1 &> out
或者 ls1 > out 2>&1
)。
5、管道和重定向很像,但是管道是一个连接一个进行计算,重定向是将一个文件的内容定向到另一个文件,这二者经常会结合使用。Linux 中的管道也是文件,有两种类型的管道:
- 匿名管道(Unnamed Pipeline),这种管道也在文件系统中,但是它只是一个存储节点,不属于任何一个目录。说白了,就是没有路径。
- 命名管道(Named Pipeline),这种管道就是一个文件,有自己的路径。用
mkfifo
指令可以创建一个命名管道(mkfifo pipe1
)。
6、去重可以使用 uniq
指令,uniq
指令能够找到文件中相邻的重复行,然后去重。
7、grep -v
是匹配不包含的结果, 比如:我们希望包含 Spring 但不包含 MyBatis 就可以这样操作:
find ./ | grep Spring | grep -v MyBatis
^ # 锚定行的开始 如:'^grep'匹配所有以grep开头的行。
$ # 锚定行的结束 如:'grep$' 匹配所有以grep结尾的行。
. # 匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。
* # 匹配零个或多个先前字符 如:'*grep'匹配所有一个或多个空格后紧跟grep的行。
--color=auto # 标记匹配颜色。
8、wc -l
用来统计行数。比如:统计 Java 文件有多少行?(wc -l Client.java
), 统计当前目录下有多少个文件?(ls | wc -l
)。
# 利用 nginx 的 access_log 统计网站的 PV(Page View),用户每访问一次页面就是一次 PV
wc -l access.log
9、tee
指令从标准输入流中读取数据到标准输出流,可以把中间的结果保存下来。比如:从当前目录中找到所有含有 Spring 关键字的 Java 文件。tee
本身不影响指令的执行,但是 tee
会把 find 指令的结果保存到 JavaList 文件中。
find ./ -iname "*.java" | tee JavaList | grep Spring
10、xargs
指令从标准数据流中构造并执行一行行的指令。xargs
从输入流获取字符串,然后利用空白、换行符等切割字符串,在这些字符串的基础上构造指令,最后一行行执行这些指令。比如:统计目录下所有 Java 文件的行数。
find ./ -iname "*.java" | xargs wc -l
11、cat pipe1
后面增加了一个 &
符号。这个 &
符号代表指令在后台执行,不会阻塞用户继续输入。
cat pipe1 &
12、文件被创建后,初始的权限如何设置?文件被创建后的权限通常是 rw-rw-r--
,也就是用户、组维度不可以执行,所有用户可读。文件被创建后,文件的所属用户会被设置成创建文件的用户,所属用户组是当时用户所在的工作分组,如果没有特别设置,那么就属于用户所在的同名分组。
13、需要全部用户都可以执行的指令,比如 ls
,它们的权限如何分配?用户维度可读写和执行,组维度和所有用户可以读和执行。到这里你可能会有一个疑问:如果一个文件设置为不可读,但是可以执行,那么结果会怎样?答案当然是不可以执行,无法读取文件内容自然不可以执行。
[root@apm-0001 ~]# ls -l /usr/bin/ls
-rwxr-xr-x. 1 root root 117680 10月 31 2018 /usr/bin/ls
14、当用户输入一个文件名,如果没有指定完整路径,Linux 就会在一部分目录中查找这个文件,你可以通过 echo $PATH
看到 Linux 会在哪些目录中查找可执行文件。
15、内核是操作系统连接硬件、提供操作硬件、磁盘、内存分页、进程等最核心的能力,并拥有直接操作全部内存的权限,因此内核不能把自己的全部能力都提供给用户,而且也不能允许用户通过 shell
指令进行调用。Linux 下内核把部分进程需要的系统调用以 C 语言 API 的形式提供出来。
16、优秀的权限架构主要目标是让系统安全、稳定且用户、程序之间相互制约、相互隔离。这要求权限系统中的权限划分足够清晰,分配权限的成本足够低。因此,优秀的架构,应该遵循最小权限原则(Least Privilege)。
17、请简述 Linux 权限划分的原则? Linux 遵循最小权限原则。
- 每个用户掌握的权限应该足够小,每个组掌握的权限也足够小。实际生产过程中,最好管理员权限可以拆分,互相牵制防止问题。
- 每个应用应当尽可能小的使用权限。最理想的是每个应用单独占用一个容器(比如 Docker),这样就不存在互相影响的问题。即便应用被攻破,也无法攻破 Docker 的保护层。
- 尽可能少的
root
。如果一个用户需要root
能力,那么应当进行权限包围——马上提升权限(比如 sudo),处理后马上释放权限。 - 系统层面实现权限分级保护,将系统的权限分成一个个 Ring,外层 Ring 调用内层 Ring 时需要内层 Ring 进行权限校验。
18、可不可以多个用户都登录 root
,然后只用 root
账户?当然不行!举个例子,你有一个 MySQL 进程执行在 root(最大权限)账户上,如果有黑客攻破了你的 MySQL 服务,获得了在 MySQL 上执行 SQL 的权限,那么,你的整个系统就都暴露在黑客眼前了。这会导致非常严重的后果。
黑客可以利用 MySQL 的 Copy From Prgram 指令为所欲为,比如先备份你的关键文件,然后再删除他们,并要挟你通过指定账户打款。如果执行最小权限原则,那么黑客即便攻破我们的 MySQL 服务,他也只能获得最小的权限。当然,黑客拿到 MySQL 权限也是非常可怕的,但是相比拿到所有权限,这个损失就小多了。
19、ifconfig
命令被用于配置和显示 Linux 内核中网络接口的网络参数。
ifconfig #处于激活状态的网络接口
ifconfig -a #所有配置的网络接口,不论其是否激活
ifconfig eth0 #显示eth0的网卡信息
ifconfig eth0 #显示eth0的网卡信息
ifconfig eth0 mtu 1500 #设置能通过的最大数据包大小为 1500 bytes
ifconfig eth0 arp #开启网卡eth0 的arp协议
ifconfig eth0 -arp #关闭网卡eth0 的arp协议
ifconfig eth0 up #启动网卡
ifconfig eth0 down #关闭网卡
20、netstat
命令用来打印 Linux 中网络系统的状态信息,可以让你得知 Linux 系统的网络情况。
# -a或--all:显示所有连线中的Socket;
# -n或--numeric:直接使用ip地址,而不通过域名服务器;
# -l或--listening:显示监控中的服务器的Socket;
# -r或--route:显示Routing Table;
# -t或--tcp:显示TCP传输协议的连线状况;
# -u或--udp:显示UDP传输协议的连线状况;
# -p或--programs:显示正在使用Socket的程序识别码和程序名称;
# -i或--interfaces:显示网络界面信息表单;
netstat -ap | grep java # 找出程序运行的端口
netstat -anp | grep 8081 | grep LISTEN | awk '{printf $7}' | cut -d/ -f1 # 通过端口找进程ID
netstat -ntu | grep :80 | awk '{print $5}' | cut -d: -f1 | awk '{++ip[$1]} END {for(i in ip) print ip[i],"\t",i}' | sort -nr # 查看连接某服务端口最多的的IP地址
netstat -nt | grep -e 127.0.0.1 -e 0.0.0.0 -e ::: -v | awk '/^tcp/ {++state[$NF]} END {for(i in state) print i,"\t",state[i]}' # TCP各种状态列表
netstat -an | tail -n +3| grep TIME_WAIT | wc -l # 查看正在 TIME_WAIT 状态的连接数量(netstat 会有两行表头,这两行可以用 tail 过滤掉)
21、ss
比 netstat 好用的 socket 统计信息,iproute2 包附带的另一个工具,允许你查询 socket 的有关统计信息。
当服务器的 socket 连接数量变得非常大时,无论是使用 netstat 命令还是直接 cat /proc/net/tcp
,执行速度都会很慢。可能你不会有切身的感受,但请相信我,当服务器维持的连接达到上万个的时候,使用 netstat 等于浪费生命,而用 ss 才是节省时间。
ss 快的秘诀在于,它利用到了 TCP 协议栈中 tcp_diag。tcp_diag 是一个用于分析统计的模块,可以获得Linux 内核中第一手的信息,这就确保了 ss 的快捷高效。当然,如果你的系统中没有 tcp_diag,ss 也可以正常运行,只是效率会变得稍慢。
# -a, --all:显示所有套接字(sockets)
# -n, --numeric:不解析服务名称
# -l, --listening:显示监听状态的套接字(sockets)
# -t, --tcp :仅显示 TCP套接字(sockets)
# -u, --udp: 仅显示 UCP套接字(sockets)
# -p, --processes:显示使用套接字(socket)的进程
ss -s # 显示 Sockets 摘要
ss -l # 列出所有打开的网络连接端口
ss -pl # 查看进程使用的 socket
ss -tan|awk 'NR>1{++S[$1]}END{for (a in S) print a,S[a]}' # 查看TCP的连接状态
22、awk 是一个处理文本的领域专有语言。那么什么是领域专有语言呢?英文是 Domain Specific Language。领域专有语言,就是为了处理某个领域专门设计的语言。比如 awk 是用来分析处理文本的 DSL,html 是专门用来描述网页的 DSL,SQL 是专门用来查询数据的 DSL。
# 对 nginx 的 access.log 进行 pv (Page views)分组
awk '{print substr($4, 2, 11)}' access.log | sort | uniq -c
# 对 nginx 的 access.log 进行 UV(Uniq Visitor)分析,统计访问人数,利用 IP 访问进行统计
awk '{print $1}' access.log | sort | uniq -c | wc -l
# 对 nginx 的 access.log 进行按天分组分析每天的 UV 情况
awk '{print substr($4,2,11) " " $1}' access.log | sort | uniq | awk '{uv[$1]++;next}END{for (day in uv) print day, uv[day]}'
# 对 nginx 的 access.log 分组统计出哪些终端访问了这些网站
awk -F\" '{print $6}' access.log | sort | uniq -c | sort -fr
# 对 nginx 的 access.log 分析出访问量 Top 前三的网页
awk '{print $7}' access.log | sort | uniq -c | head -n 3