Linux Instruction Usage Guide

Linux 内核支持指令使用指南。

本文仅提供常见的 Linux 内核支持指令以及其常用选项的使用,指令详细使用可通过 command --help 以查看其使用帮助信息。


The Basics

Linux OS 中一切都是文件,命令(指令)也是文件,是一种二进制文件。

[1] >>> Linux Shell 命令行(Command Line)含义

1
2
3
4
5
6
7
8
9
10
11
12
13
# 示例 1:
[root@hostname:~]#
root // 登录用户名,root 为超级用户;
@ // 分隔符,可理解为:登入
hostname // 主机名,指当前服务器名称
~ // 当前所在目录,root 默认用户目录为 ~(/root),会随着目录切换而显示当前所在目录路径;
# // 命令输入的提示符(超级用户为 #;普通用户为 $),在其后输入命令

# 示例 2:
[user@hostname:~]$
user // 登录用户名,其它普通用户;
~ // 当前所在目录,普通用户的默认用户目录为 ~(/home/user),会随着目录切换而显示当前所在目录路径;
$ // 命令输入的提示符(超级用户为 #;普通用户为 $),在其后输入命令

[2] >>> Command Format

Linux 中通用的命令格式(命令组成):

1
2
# 命令 选项 参数(操作对象)
Command Options arguments

Shell 中可使用快捷键 Ctrl + c 终止命令的执行。

[3] >>> Basic Command

查询系统当前时间:

1
2
$ date
Wed Mar 13 18:45:38 CST 2024

关闭/重启计算机:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
### 1. 关机 ###
# 立刻关机:
$ shutdown -h now // 或者:poweroff / halt

# 定时关机:
$ shutdown -h 20 // 指定二十分钟后关机
$ shutdown -h 20:30 // 指定于 20:30 关机
# 取消定时关机:
$ shutdown -c


### 2. 重启 ###
# 立刻重启:
$ shutdown -r now // 或者:reboot

# 定时重启:
$ shutdown -h 20 // 指定二十分钟后重启
$ shutdown -h 20:30 // 指定于 20:30 重启
# 取消定时重启:
$ shutdown -c


# shutdown 命令为安全的关闭/重启命令。
# 设置定时后,会广播提醒所有登录用户 Shutdown Scheduled,以尽快处理未完成工作。
# 样例:
$ date
Wed Mar 13 18:42:41 CST 2021
$ shutdown -h 20
Shutdown scheduled for Wed 2021-03-13 19:02:50 CST, use 'shutdown -c' to cancel.

$ shutdown -c
Broadcast message from root@localhost.localdomain (Wed 2021-03-13 18:43:40 CST):
The system shutdown has been cancelled at Wed 2021-03-13 18:44:40 CST!

查看命令帮助(Command –help):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 示例:
$ shutdown --help
shutdown [OPTIONS...] [TIME] [WALL...]

Shut down the system.

--help Show this help
-H --halt Halt the machine
-P --poweroff Power-off the machine
-r --reboot Reboot the machine
-h Equivalent to --poweroff, overridden by --halt
-k Don't halt/power-off/reboot, just send warnings
--no-wall Don't send wall message before halt/power-off/reboot
-c Cancel a pending shutdown

切换用户:

1
2
3
4
5
# Switch User:
$ su root // 切换为超级用户:root,需要输入该用户的密码
$ su // 等同于 su root

$ exit // 推出当前用户,或 Shell

临时获取超级用户权限以执行命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Linux 默认规则:命令存放的路径不同,其执行权限不同。
# 故,Linux 指令可以被分为:root 指令,或 user 指令
# root 指令(root 权限下可以执行):/sbin 或者 /usr/sbin
# all users 指令(所有用户都可以执行):/bin 或者 /usr/bin
#
# 可以理解为:bin=binary ;sbin=super binary;
#
# 当普通用户想要执行某个 root 指令时,需要使用 sudo 获取临时超级用户权限,执行时需要输入 root 用户密码。示例:
[centos@localhost ~]$ shutdown -h 20
Must be root.
[centos@localhost ~]$ sudo shutdown -h 20
[sudo] password for centos:
Shutdown scheduled for Wed 2024-03-13 20:39:04 CST, use 'shutdown -c' to cancel.
[centos@localhost ~]$ shutdown -c
Failed to talk to shutdownd, shutdown hasn't been cancelled: Permission denied
[centos@localhost ~]$ sudo shutdown -c

Broadcast message from root@localhost.localdomain (Wed 2024-03-13 20:19:51 CST):

The system shutdown has been cancelled at Wed 2024-03-13 20:20:51 CST!

清除 Shell 中的命令历史(清屏):

1
$ clear 

Shell 命令行中发现输入了错误命令后,可以使用快捷键 Ctrl + u 清除掉光标前所有内容。

查看主机名:

1
2
3
4
5
6
7
# 查看主机名:
$ hostname // 主机名.域名:<localhost.localdomain>

# 临时设置主机名:
$ hostname centos
$ hostname
centos

查看当前所在的工作目录:

1
2
3
# Print Working Directory:
$ pwd
$ /home/centos

File Processing

这里我们来看文件处理相关的命令:

  • cd
  • ls=dir
  • touch
  • mkdir
  • rm
  • cp
  • mv
  • cat/more/less/head/tail
  • vi/vim

[1] >>> cd (Change Directory)

功能描述:可用于切换当前的工作目录。

语法格式:cd [dir],命令使用示例:

1
2
3
4
5
6
7
8
9
10
$ cd /                 // 切换到根目录
$ cd /etc // 切换到根目录下的 etc 配置目录
$ cd ~ // 切换到当前用户的默认用户名录:/root 或者 /home/user

# 两个特殊的目录 "." 和 ".." ,分别代表 "当前目录" 和 "当前目录的父目录"
$ cd .. // 切换到上一级目录,等同于:cd ../
$ cd ../.. // 切换到上上级目录
$ cd - // 切换到上次访问的目录

$ cd /xxx/xx/x // 通过完整的目录路径(支持 Tab 键快速补全),直接切换到目标目录(不存在则:No such file or directory)

[2] >>> ls (List) == dir (Directory)

功能描述:查看目录或文件。

语法格式:cd [Options:a/l/d/i] [dir/file],命令使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 常用选项说明:
# a :显示所有文件,包括隐藏文件
# l :列表显示更详细的信息(执行权限/所属用户、组/文件大小/...)
# d :查看某特定目录的属性,配合 -l 使用
# i :查看文件的 inode Number

$ ls // 查看当前目录下的所有目录和文件
$ ls -a // 查看当前目录下的所有目录和文件(包括隐藏的文件)
$ ls -l // 以列表形式(List)查看当前目录下的所有目录和文件,等同于:ll
$ ls / // 查看指定目录(根目录)下的所有目录和文件

$ ls -ld // 查看当前目录的属性信息
drwx------. 16 centos centos 4096 Mar 13 20:58 .
$ ls -l /xxx/dir // 查看某个目录的详细信息(dir 所在目录中文件较多时)
$ ls -l /xxx/xx/file // 查看某个指定文件的详细信息(file 所在目录中文件较多时)

查看到的文件信息 drwxr-xr-x 2 root root 4096 Mar 13 21:43 格式说明:

1
2
3
4
5
6
# 首字符 d:表示文件类型,常见的有 "d" >>> Dir(目录);"-" >>> 二进制文件;"l" >>> Link(软连接文件)
# rwx(u) | r-x (g) | r-x (o):表示文件的权限信息,每三个字符间隔一下,分别表示([所有者(u)] | [所属组(g)] | [其他人(others)])对文件的操作权限,其中 r--read 读;w--write 写;x--execute 执行
# 2:表示硬链接数(文件的硬连接数为 1,目录的硬链接数为其下所有子文件夹的个数)
# root root:告诉我们当前文件的所有者(root)和所属组(root 组:r-x 权限)
# 4096:表示文件大小,有时以 block 为单位
# Mar 13 21:43:表示文件的创建或最后修改时间

[3] >>> touch

功能描述:创建空文件;如果文件存在,则修改文件时间属性为当前系统时间。

语法格式:touch [file],命令使用示例:

1
$ touch test.txt         // 在当前目录下创建名为 test 的 txt 文件(文件不存在),如存在则修改其时间属性为当前系统时间

[4] >>> mkdir (Make Directory)

功能描述:创建新目录;如果文件存在,则产生错误 File exists。

语法格式:mkdir [dir],命令使用示例:

1
2
$ mkdir temp         // 在当前目录下创建名为 temp 的目录
$ mkdir ~/temp // 在指定目录(默认用户目录)下创建一个名为 temp 的目录

[5] >>> rm (Remove)

功能描述:删除已存在文件(File)或目录(Dir);如果文件不存在,则产生错误 No such file or directory。

语法格式:rm [Options:r/f] [file/dir],命令使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 常用选项说明:
# r (recursive):递归删除目录,以及目录中的所有文件/目录
# f (force) :强制删除,不询问

### 1. File ###
rm test.txt // 删除当前目录下的 test.txt 文件,删除时会询问你是否删除(yes/no)?
rm -f test.txt // 删除当前目录的的 test.txt 文件(不询问)


### 2. Dir ###
rm -r temp // 递归删除当前目录下名为 temp 的目录,以及其下的所有内容(文件/目录),删除每一个文件/目录均会询问
rm -rf temp // 递归删除当前目录下名为 temp 的目录,以及其下的所有内容(文件/目录),删除时不询问

rm -rf * // 删除当前目录下的所有(目录/文件)
rm -rf temp/* // 删除 temp 目录下的所有(目录/文件)

还有一个命令 rmdir 来删除目录,但只能删除空目录(Empty Dir)。


[6] >>> cp (Copy)

功能描述:复制/备份 文件(File)或目录(Dir);如果文件不存在,则产生错误 No such file or directory。

语法格式:cp [Options:r/R] [src file/dir] [target file/dir],命令使用示例:

1
2
3
4
5
6
7
8
# 复制文件:cp [src file] [target dir]
# 复制目录:cp -R [src dir] [target dir]

$ cp file1 dir1 // 将当前目录下的 file1 文件复制到目录 dir1 下(dir1 目录存在),若 dir1 中存在 file1,会进行覆盖 overwrite;若 dir1 不存在意为将 file1 复制并改名为 dir1。

$ cp file1 file2 dir1 // 将当前目录下的 file1 && file2 文件复制到目录 dir1 下;若 dir1 中存在 file1 / file2,会进行覆盖 overwrite;若 dir1 不存在会报错。

$ cp -R dir1 dir2 // 将当前目录下的 dir1 目录复制到目录 dir2 下(dir1 目录存在),若 dir2 目录下存在 dir1 目录,会进行合并,存在相同文件时会进行覆盖 overwrite;若 dir2 目录不存在意为将 dir1 复制并改名为 dir2。

[7] >>> mv (Move)

功能描述:改名/移动 文件(File)或目录(Dir);如果文件不存在,则产生错误 No such file or directory。

语法格式:mv [Options] [src file/dir] [target file/dir],命令使用示例:

1
2
$ mv dir1 dir2            // dir2 存在,则移动;不存在,则改名。
$ mv file1 dir1/dir2 // 将当前目录下的文件 file1 移动到 dir2 目录下(dir2 目录存在);如果 dir2 不存在,则意为将 file1 移动并改名为 dir1。

[8] >>> cat/more/less/head/tail

功能描述:查看文件内容。

语法格式和使用说明较为简单,如下:

1
2
3
4
5
6
7
8
# cat [file]                     // 查看文件最后一屏内容(文件较短时使用)
# more [file] // 分页显示文件内容(文件较长时使用):显示查看文件进度百分比,BlackSpace 翻页,Enter 下一行,q 退出查看
# less [file] // 分页显示文件内容(文件较长时使用):PgUp 向上翻页,PgDn 向下翻页,q 退出查看

# head [Options: n] [file] // 查看文件头 n 行的内容(默认 10 行):tail -n 20
# tail [Options: n/f] [file] // 查看文件尾部 n 行的内容(默认 10 行):tail -n 20

$ tail -n 5 -f log.txt // 动态显示文件内容:用来监控日志文件时才有价值

[9] >>> vi/vim

关于 Linux 中文本编辑器命令 vi/vim 的使用,可以参见【Linux 常用文本编辑器 Vi && Vim 使用指南】中说明。


Command Help

Linux 系统中的帮助命令:

Command –help

Linux 系统中的命令,一般都提供了 Command --help 形式,以查看相应命令的简单帮助信息(命令格式、选项等)。

你可以通过 Command --help 快速掌握某个命令的快速使用。


man/info

man 命令可用于查看系统中某个命令、系统调用或库函数等的使用手册(manuals)。

一个 man 手册遵守下面的章节结构:

↓↓↓↓↓↓ man 手册的数字编号 ↓↓↓↓↓↓

man 1 kill && man 2 kill,这些命令都是查看 kill 命令的手册,但是文档却大不相同。

因为 kill 是一个命令行的工具,which kill 看到 /usr/bin/kill 是一个二进制文件;其实,也有一个系统调用叫做 kill。

  • man 1 kill >>> 显示的是命令行工具 kill 的手册
  • man 2 kill >>> 显示系统调用 kill 的手册

显示什么类型的手册,由 man 和命令中间的数字决定,目前共有 9 个 man 支持的数字:

↓↓↓↓↓↓ man 手册阅读 ↓↓↓↓↓↓

BlackSpace 空格翻页;/ 可进入查找关键字模式;其使用类似于 Vim。


whatis/apropos

可以看见,man 手册中提供的帮助信息太多了,如果我们只想获得简短说明信息,可以使用 whatis/apropos 命令。

whatis [任何关键字] 可获取关键字的简单功能描述;而 apropos [配置文件] 以查看配置文件的详细信息。


Permission Management

在前面的 ls 命令中,已经接触过文件的权限信息(rwxr-xr-x)了,这里首先来简单的说明一下 Linux 系统中的文件权限:

👇👇👇 文件权限说明 👇👇👇

以某文件的权限信息 rwxr-xr-x 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
### 文件的权限由三组字符构成,表示三种不同的用户对文件的访问权限 ###
第一组三位(rwx):表示 拥有者(user)的权限
第二组三位(r-x):表示 拥有者所在的组(group),即组员的权限
第三组三位(r-x):表示 其他用户的权限(others)

每一种用户,针对某个特定的文件,又有三种(三位)访问权限:'r' 代表可读(4),'w' 代表可写(2),'x' 代表可执行权限(1),括号内代表 "8421 法"。


8421 法:用户对文件的访问权限,可以使用三位二进制数表示:`111`,每一位分别代表 'r' & 'w' & 'x'
故,'r' 代表可读(4),'w' 代表可写(2),'x' 代表可执行权限(1)
三位数相加和为 1+2+4=7,表示当前用户对该文件具有 “可读、可写、可执行” 的权限,即授予该用户所有权限

于是,文件权限 `rwxr-xr-x` 表示为 8421 法的写法为:`755`
即:拥有者(u)对文件具有 rwx 权限;拥有者所在的组(g)对对文件具有 rx 权限;而其它用户(o)对该文件具有 rx 权限。

↓↓↓↓↓↓ rwx 权限的深入理解 ↓↓↓↓↓↓

Example 1 >>>

在 root 权限下在 / 目录下创建 practice 目录(755:drwxr-xr-x),再在该目录下创建 test 文件(744:drwxr–r–),然后将 test 文件权限改为 777(-rwxrwxrwx),思考在用户权限下是否可以删除文件 test ?!!

答案是 >>> 操作无法实现,权限不够!!!

如果将 practice 目录权限修改为 777,那么上述操作是可以实现的。

对文件而言:w 权限代表用户可以修改文件,而不是删除。删除时,需要看当前操作用户对其所属目录是否具有 w 权限!!!

Example 2 >>>

1
2
3
4
5
6
7
8
9
10
11
12
# 普通用户 centos 下无法 查看/进入 超级用户 root 的默认用户目录(/root):
centos@localhost ~]$ ls /root/
ls: cannot open directory /root/: Permission denied
[centos@localhost ~]$ cd /root/
bash: cd: /root/: Permission denied

# sudo 查看一下 /root 目录的权限信息:
[centos@localhost ~]$ sudo ls -ld /root
[sudo] password for centos:
dr-xr-x---. 5 root root 261 Mar 14 20:45 /root

# 可见,其它用户对于 /root 目录没有任何权限

下面我们来看文件权限管理相关的命令:

[1] >>> chmod (Change Mode)

功能描述:更改 文件(file)或目录(Dir)权限。

语法格式:chmod [{ugo}{+-=}{rwx}] [file/Dir] 或者 chmod [mode=421] [file/Dir],命令使用示例:

1
2
$ chmod u+rw test.txt    # 为 test.txt 文件的所有者增加读写权限
$ chmod 775 test.txt # 修改 test.txt 文件的权限为:rwx-rwx-r-x

[2] >>> chown (Change Ownership)

功能描述:更改 文件(file)或目录(Dir)的所有者。

语法格式:chown [user] [file/Dir],命令使用示例:

1
$ chown centos file1        # 改变文件 file1 的所有者为 centos

[3] >>> chgrp (Change Group)

功能描述:更改 文件(file)或目录(Dir)的的所属组。

语法格式:chgrp [user-group] [file/Dir],命令使用示例:

1
$ chgrp adm file1        # 改变文件 file1 的所属组为 adm

不知道你有没有思考过一个问题 >>>

文件在创建时就被授予了初始权限,那么 Linux 系统是如何给新建的文件授权的呢?!!

[4] >>> umask

功能描述:显示 && 设置 新建文件[New File] 或 目录(Dir)的缺省权限。

语法格式:umask [Options:S] [file/Dir],命令使用示例:

1
2
3
4
5
6
7
8
# 以权限掩码值显示新建文件或目录的缺省权限(777 - 权限值 = 权限掩码值)
$ umask

# 以 rwx 的形式显示新建文件或目录的缺省权限
# umask -S

# 修改新建文件或目录的缺省权限
$ umask [权限掩码值]

实际环境测试:

1
2
3
4
5
6
7
8
9
# 查看普通用户的缺省权限
[centos@localhost ~]$ umask
0002

# 查看 root 用户的缺省权限
[centos@localhost ~]$ su root
Password:
[root@localhost centos]# umask
0022

↓↓↓↓↓↓ 关于 0002/0022 ↓↓↓↓↓↓

最高位的 0 表示特殊权限位;002/022 是用户权限位,其权限值 = 777 - 002/022(775/755),rwx 形式为:rwxrwxr-x && rwsr-xr-x

1
2
3
4
5
[centos@localhost ~]$ umask -S
u=rwx,g=rwx,o=rx

[root@localhost centos]# umask -S
u=rwx,g=rx,o=rx

修改普通用户的文件缺省权限

1
2
3
4
5
6
[centos@localhost ~]$ umask 022

[centos@localhost ~]$ umask
0022
[centos@localhost ~]$ umask -S
u=rwx,g=rx,o=rx

Linux 中文件查找或文件内容查找相关的命令:

find

功能描述:通过设定条件(文件名/文件权限/大小/时间/inode),查找指定路径下的 文件(File)或 目录(Dir)。

使用须知:使用 find 命令搜索时,不要指定过大的搜索范围(find 直接在硬盘中进行搜索的,如果指定的搜索范围过大,会消耗较大的系统资源,导致服务器压力过大)。

语法格式:fine path -Options [-print] [-exec -ok |xargs |grep] [command {} \;],参数说明:

1
2
3
4
5
6
7
# path                    >>>> 指定搜索(查找)路径

# -print >>>> 表示将结果输出到标准输出(只对离自己最近的一个匹配条件起作用)

# -exec >>>> 对查找匹配到的文件,执行其后所给出的 Shell 命令:[command {} \;]
# -ok >>>> 功能等同于 exec;但执行命令会进行询问,让用户确认是否执行
# |xargs >>>> 功能等同于 exec ,起承接作用;|xargs 主要用于承接删除操作,而 -exec 都可用(删除、复制、移动、重命名等)

| ================================================== Split Line =============================================== |

常用 Options 查找条件示例:

↓↓↓↓↓↓ -name/iname 按文件名称查找文件 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 在 /dir 目录及其子目录下面查找名字为 filename 的文件(完全匹配)
$ find /dir -name filename
# 在 /dir 目录及其子目录下面查找名字为 filename 的文件(完全匹配),不区分大小写
$ find /dir -iname filename

# 在 /dir 目录及其子目录中,查找扩展名为 “c” 的文件
$ find /dir -name "*.c"
# 在当前目录及子目录中,查找大写字母开头的 txt 文件
$ find . -name '[A-Z]*.txt' -print
# 在 /etc 及其子目录中,查找 host 开头的文件
$ find /etc -name 'host*' -print
#$HOME 目录及其子目录中,查找所有文件
$ find ~ -name '*' -print

# 在当前目录及子目录中,查找不是 out 开头的 txt 文件(忽略以 out 开头的文件)
$ find . -name "out*" -prune -o -name "*.txt" -print

↓↓↓↓↓↓ -path 按目录查找 ↓↓↓↓↓↓

1
2
3
4
5
6
# 在当前目录除 git 子目录外查找 txt 文件
find . -path "./git" -prune -o -name "*.txt" -print

# 在 temp/ 目录下除 test 和 valid 之外的子目录中查找 txt 文件
$ find temp/ \( -path 'temp/test' -o -path 'temp/valid' \) -a -prune -o -name '*.txt' -print
# 注意:`\( -path 'temp/test' -o -path 'temp/valid' \)` 中表达式结合符 () 其前后均有空格,并使用 \ 进行转义

↓↓↓↓↓↓ -inum 按文件节点号查找 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 根据文件的 inode number 来查找其所有硬链接

# Example >>>
# 创建硬链接:
$ ln temp/test.txt tmp/test.txt
$ ll -i temp/test.txt tmp/test.txt
# 查看两个文件的 inode number:
6010092 -r--r--r--. 2 centos centos 105 Mar 14 21:12 temp/test.txt
6010092 -r--r--r--. 2 centos centos 105 Mar 14 21:12 tmp/test.txt


# 根据节点号查找所对应的文件:
$ find . -inum 6010092
./temp/test.txt
./tmp/test.txt

↓↓↓↓↓↓ -perm 按文件权限查找 ↓↓↓↓↓↓

1
2
3
4
5
6
7
# 在当前目录及子目录中,查找具有 u(7)&& g(5)&& o(5)权限的文件或目录
$ find . -perm 755 –print

# 在当前目录及子目录中,查找具有 u(2)&& g(2)权限的文件或目录
$ find ./ -perm /220
$ find ./ -perm /u+w,g+w
$ ind ./ -perm /u=w,g=w

↓↓↓↓↓↓ -use/nouser/group/nogroup 按文件所属用户及所属用户组查找 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
9
10
11
#$HOME 目录中查找文件属主为 sam 的文件
$ find ~ -user sam –print

# 查找无有效属主的文件,即其属用户在 /etc/passwd 中不存在(用户被删除)
$ find /home -nouser –print

# 在 /apps 目录下查找属于 mysql 用户组的文件
$ find /apps -group mysql –print

# 查找无有效所属组的文件,即其所属的用户组在 /etc/groups 中不存在(用户组被删除)
$ find / –nogroup -print

↓↓↓↓↓↓ -mtime/atime/ctime 按文件(更改/访问/状态)时间查找 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查找 2 天内被更改过的文件 
$ find . -mtime -2 -type f -print
# 查找 2 天前被更改过的文件
$ find . -mtime +2 -type f -print

# 查找一天内被访问的文件
$ find . -atime -1 -type f -print
# 查找一天前被访问的文件
$ find . -atime +1 -type f -print

# 查找一天内状态被改变的文件
$ find . -ctime -1 -type f -print
# 查找一天前状态被改变的文件
# $ find . -ctime +1 -type f -print


# 理解 >>> +2(2 天前,比两天多)/ -2(2 天以内,比两天少)

↓↓↓↓↓↓ -newer 按文件新旧(更改时间)查找 ↓↓↓↓↓↓

1
2
3
4
5
6
7
# 查找比 aa.txt 新的文件
$ find . -newer "aa.txt" -type f -print
# 查找比 aa.txt 旧的文件
$ find . ! -newer "aa.txt" -type f -print

# 查找比 aa.txt 新,比 bb.txt 旧的文件
$ find . -newer 'aa.txt' ! -newer 'bb.txt' -type f -print

↓↓↓↓↓↓ -size 按文件大小查找 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
# 查找超过 1M 的文件
$ find / -size +1M -type f -print

# 查找等于 100 字节 的文件
$ find . -size 100c -print

# 查找小于 32k 的文件
$ find . -size -32k -print

↓↓↓↓↓↓ -mount 查找时不跨越文件系统 mount 点 ↓↓↓↓↓↓

1
2
# 从当前目录开始查找位于本文件系统中文件名以 XC 结尾的文件(不进入其他文件系统)
$ find . -name '*.XC' -mount –print

↓↓↓↓↓↓ -type 按文件类型查找 ↓↓↓↓↓↓

查找某一类型的文件:

  • b - 块设备文件,比如磁盘;
  • d - 目录
  • c - 字符设备文件,比如鼠标键盘网卡;
  • p - 管道文件;
  • l - 符号链接文件;
  • f - 普通文件
1
2
3
4
5
6
7
#$HOME 目录下查找所有的目录
$ find ~ -type d –print
# 在当前目录下查找,除目录以外的所有类型的文件
$ find . ! -type d –print

# 在 /etc 目录下查找所有的符号链接文件
$ find /etc -type l –print

↓↓↓↓↓↓ -a/-o/-not 支持逻辑运算 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
# 在当前目录下搜索大于 2KB,并且文件类型是普通文件的文件:
$ find.-size +2k -a -type f

# 在当前目录下搜索文件名要么是 test 开头的文件,要么是 valid 开头的文件
$ find /etc/init -name "test*" -o -name "valid*"

# 在当前目录下搜索文件名不是 test 的文件
$ find. -not -name test

↓↓↓↓↓↓ -exec/-ok 对查找匹配到的文件,执行其后所给出的 Shell 命令:[command {} ;] ↓↓↓↓↓↓

1
2
3
4
5
6
7
# 删除文件大小为零的文件
$ find ./ -size 0 -exec rm {} \;
$ rm -i `find ./ -size 0`

# -ok 以一种更为安全的模式(询问),执行其后所给出的 Shell 命令
# 在当前目录中查找所有文件名以 .LOG 结尾、更改时间在 5 日以上的文件,并删除它们,只不过在删除之前先给出提示
find . -name "*.conf" -mtime +5 -ok rm { } \;

一些常用组合命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 查找当前路径下的所有普通文件,并把它们列出来查看其详细信息:
$ find . -type f -exec ls -l {} \;

# 删除 logs 目录下更新时间为五日以上的文件:
$ find logs -type f -mtime +5 -exec rm {} \;

# 删除当前路径下以 .log 结尾的五日以上的文件,删除之前要确认:
find . -name "*.log" -mtime +5 -ok rm {} \;

# 查找 test.txt 并备份为 test.txt.bak
$ $ find . -name 'test.txt' -exec cp {} {}.bak \;

# 查询当天修改过的文件:
$ find ./ -mtime -1 -type f -exec ls -l {} \;

# 删除一些特殊很难删除的文件(\-abc、“a b”):
$ find . -name "*abc" -print -ok rm {} \;
./\-abc
< rm ... ./\-abc > ? yes



# find 在有些系统中会一次性得到将匹配到的文件都传给 exec,但系统对 exec 的命令长度做限制,就会产生:“参数列太长” 的异常。
# xargs 登场了~~~~ xargs 是部分取传来的文件。


# 使用 xargs 测试文件分类
$ find / -type f -print |xargs file

# 将 core 文件信息查询结果报存到 core.log 日志:
$ find . -name "core*" -print |xargs echo " ">/tmp/core.log

$ find . -name * -print |xargs grep "DBO"

| ================================================== Split Line =============================================== |

👇👇👇 有没有 -print 的区别 👇👇👇

以查找目录并列出目录下的文件为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 加 -print
[root@localhost centos]# find temp/ -type d -print -exec ls {} \;
temp/
test test.txt TEST.txt valid
temp/valid
test.txt valid.txt
temp/test
test.txt

# 不加 -print
[root@localhost centos]# find temp/ -type d -exec ls {} \;
test test.txt TEST.txt valid
test.txt valid.txt
test.txt

为找到的每一个目录单独执行 ls 命令,没有选项 -print 时文件列表前一行不会显示目录名称。


grep

功能描述: 从文件中(File)查找与 文本模式(Pattern)匹配的行并输出。

使用需知:一般不单独使用,通常与管道 | 配合使用,以过滤某个命令的输出。

语法格式:grep [Options] Pattern [file....],常见 Options 说明:

1
2
3
4
5
6
7
8
9
-?                           >>>> 同时显示匹配行上下的几行 (grep -2 pattern filename 同时显示匹配行的上下 2 行内容)
-c(--count) >>>> 只打印匹配的行数(不显示匹配内容)
-h(--no-filename) >>>> 当搜索多个文件时,不显示匹配文件名前缀。
-i(--ignore-case) >>>> 匹配时忽略大小写差别
-l(--files-with-matches) >>>> 打印匹配的文件清单
-L(--files-without-match) >>>> 打印不匹配模板的文件清单
-n(--line-number) >>>> 在匹配的行前面打印行号
-v(--revert-match) >>>> 反检索(只显示不匹配的行)
-V(--version) >>>> 显示软件版本信息

关于文本匹配模式 Pattern 的用法,即正则表达式用法,可见【一文学会正则表达式语法】。

grep 使用样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 常见用法格式:Command | grep pattern
$ ls -l | grep '^a' # 通过管道过滤 ls -l 输出的内容,只显示以 a 开头的行。


$ grep 'test' d* # 显示所有名称以 d 开头的文件中,包含 test 的行
$ grep 'test' aa bb cc # 显示 aa,bb,cc 文件中,匹配 test 的行

$ grep -i pattern files # 不区分大小写地搜索。默认情况区分大小写
$ grep -l pattern files # 只列出匹配的文件名,
$ grep -L pattern files # 列出不匹配的文件名,
$ grep -w pattern files # 完全匹配(匹配 magic,而不是 magical)
$ grep -c number pattern files # 分别显示匹配的上下文 [number] 行,同 Options `-?`
$ grep pattern1 | pattern2 files # 显示匹配 pattern1 或 pattern2 的行,
$ grep pattern1 files | grep pattern2 # 显示既匹配 pattern1 又匹配 pattern2 的行。

# 多文件查找
$ grep --count forth temp/test.txt temp/valid/test.txt
temp/test.txt:1
temp/valid/test.txt:1

which/whereis

查找命令文件的相关信息:

[1] >>> which

功能描述: 从系统环境变量 PATH(echo $PATH)中,搜索某个系统命令的位置,并返回第一个搜索结果。

作用 >>> 可用于查看某个系统命令是否存在?!!以及当前系统环境中执行的到底是哪一个位置(版本)的命令。

语法格式:which [Command],使用样例如下:

1
2
3
$ which ll
alias ll='ls -l --color=auto'
/usr/bin/ls

可以发现,使用 which 查看时,还会显示查询系统命令的别名(alias)。

| ================================================== Split Line =============================================== |

[2] >>> whereis

功能描述: 只能用于程序名的搜索。

作用 >>> 可用于查看系统中某个程序(命令)相关的:二进制文件(binary) && man 帮助说明文件(man) && 源代码文件(source)。

语法格式:which [Options:b/m/s] [Command],使用样例如下:

1
2
3
4
5
6
7
8
9
# whereis vim
vim: /usr/bin/vim /usr/share/vim /usr/share/man/man1/vim.1.gz

[root@localhost centos]# whereis -b vim
vim: /usr/bin/vim /usr/share/vim
[root@localhost centos]# whereis -m vim
vim: /usr/share/man/man1/vim.1.gz
[root@localhost centos]# whereis -s vim
[root@localhost centos]#(未查询到源码文件)

locate/updatedb

本地文件信息数据库模糊查找:

[1] >>> locate

功能描述: 从系统文件信息数据库中搜索 >>> 常用命令(Command)&& 文件(File)&& 关键字(Keywords),速度非常快。

使用须知 >>> 不搜索具体目录,而是搜索一个包含本地所有文件信息数据库(Linux 自动创建该数据库,并且每天自动更新一次,可能查询不到最新创建的文件)。

语法格式:locate [Options] [Pattern],使用样例如下:

1

当新创建一个文件时,此时数据库还没有更新,此时使用 locate 快速定位新产生文件,是无法找到的。可以在使用前配合 updatedb 命令更新数据库:

1
$ updatedb

[2] >>> updatedb 用于建立/更新整个系统文件信息的数据库


File Decompression

Windows && Linux 中常见的压缩文件格式:

1
2
3
4
.zip && .rar               >>>> Windows OS 中常见压缩文件扩展名
tar >>>> Linux OS 中打包文件的扩展名
.gz >>>> Linux OS 中压缩文件的扩展名
.tar.gz >>>> Linux OS 中打包并压缩文件的扩展名

你应当掌握上述文件格式的打包、解压缩方法,以应对某些特殊场景需要:

| ================================================== Split Line =============================================== |

gzip/gunzip

Linux 下的文件解压缩:

[1] >>> gzip

功能描述: 压缩文件(File),生成 .gz 压缩文件。

使用须知 >>> 只能压缩文件(File),不可以压缩目录(Dir),并且不保留原文件。

语法格式:gzip [Options:v/d/t] [File...],使用样例如下:

1
2
3
4
5
6
7
# 压缩文件 file,并显示命令执行过程信息:
$ gzip -v file
# 检查压缩文件完整性:
$ gzip -vt file.gz

# 可以使用 -d 参数,对 .gz 文件进行减压:
$ gzip -vd test.txt

某文件被压缩后,无法直接使用 cat 命令查看文件内容,你可以:

1
2
3
4
5
$ zcat file.gz

# 或者:

$ vim file.gz

[2] >>> gunzip

功能描述: 解压缩文件(File.gz)

使用须知 >>> “gunzip -r” 依然只会递归解压缩指定目录下的压缩文件(.gz),而不会解打包(.tar)。

语法格式:gunzip [Options:r/v] [File...],使用样例如下:

1
2
3
4
5
# 解压 file.gz 压缩文件,并显示命令执行过程信息:
$ gunzip -v file.gz

# 递归解压目录 dir1 下的所有 .gz 压缩文件,并显示命令执行过程信息:
$ gunzip -rv dir1

tar

功能描述:能够将一组文件和目录打包成单个归档文件(.tar),也可以从归档文件中提取出文件和目录。

使用须知 >>> 通过结合不同的选项,你可以实现 文件管理、备份和解压缩等功能。

语法格式:tar [Options] [File]...,常用选项及其功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
-c                           >>>> 创建新的归档文件(打包)
-x >>>> 从归档文件中提取文件(解包)

-f <filename> >>>> 指定归档文件名

-v >>>> 显示操作的详细信息

-z >>>> 通过 gzip 解压缩归档文件
-j >>>> 通过 bzip2 解压缩归档文件

-C <Dir> >>>> 切换到指定目录
--exclude=<pattern> >>>> 排除匹配模式的文件
--list >>>> 列出归档文件中的内容

使用样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
### 1. 打包文件和目录 ###
#
# 将 /home/user/documents 目录打包(-c)成一个,名为(-f) documents.tar 的归档文件(包含了 documents 目录下的所有内容):
$ tar -cf documents.tar /home/user/documents

### 2. 解包归档文件 ###
#
# 将特定(-f)归档文件 documents.tar 解包(-x)到当前目录,以提取归档文件中内容:
$ tar -xf documents.tar


### 3. 压缩归档文件 ###
#
# 可以在归档文件的同时,使用压缩工具(-z/-f)压缩归档文件,以创建压缩的归档文件(documents.tar.gz):
$ tar -zcvf documents.tar.gz /home/user/documents

### 4. 解压缩归档文件 ###
#
# 可以对压缩的归档文件(documents.tar.gz),执行先解压缩,然后解包归档文件的操作:
$ tar -zxvf documents.tar.gz


### 5. 列出归档文件内容 ###
#
# 可以使用 --list 选项来列出指定(-f)归档文件中的内容,而无需实际解包:
$ tar --list -f documents.tar


### 6. 排除特定文件 ###
#
# 可以使用 --exclude 选项来指定要排除的文件或目录的模式(`*.txt`),以避免将其包含在归档中:
$ tar -cf documents.tar --exclude='*.txt' /home/user/documents


### 7. 保留文件权限和所有权 ###
#
# 可以通过 --preserve-permissions 选项来创建一个保留权限和所有权的归档文件:
$ tar --preserve-permissions -cf documents.tar /home/user/documents


### 8. 保留时间戳 ###
#
# 备份时,可以通过 --atime-preserve 选项来保留文件的访问时间戳:
$ tar --atime-preserve -cf backup.tar /path/to/backup


### 9. 增量备份 ###
#
# 结合使用 --listed-incremental 选项和一个状态文件,来进行增量备份(只备份自上次备份以来发生更改的文件),以节省时间和存储空间:
$ tar --create --file=backup-$(date +%Y%m%d).tar --listed-incremental=backup.snar /path/to/backup
#
# 这将创建一个带有日期后缀的增量备份归档文件,并使用 backup.snar 文件来跟踪文件状态。


### 10. 使用文件列表 ###
#
# 可以通过 --files-from 选项,来从一个文件列表中读取要包含在归档中的文件和目录:
$ tar -cf backup.tar --files-from=files.txt


### 11. 压缩级别控制 ###
#
# 在压缩归档文件时(-zcvf),使用不同的压缩级别来平衡压缩速度和压缩率(压缩级别越高,压缩率越高,但耗时也越长);
# 可以在使用 -z 选项的同时,指定不同的压缩级别(1-9):
$ tar -czvf documents.tar.gz -9 /home/user/documents

zip/unzip

zip 是个使用广泛的压缩程序,文件经它压缩后会另外产生具有 .zip 扩展名的压缩文件。安装方式:

1
2
3
4
5
# For Ubuntu/Debian
sudo apt-get install zip unzip

# For CentOS
yum -y install zip unzip

Linux 中 zip 命令用于压缩文件,unzip 命令用于解压文件。

| ================================================== Split Line =============================================== |

[1] >>> zip

功能描述:用来压缩文件(.zip)或目录(Dir),以实现对文件或目录的打包(归档)。

语法格式:zip [Options] [File]...,常用选项及其功能:

1
2
3
4
5
6
7
-r                           >>>> 递归地将一个目录及其所有子目录和文件压缩到 ZIP 文件中
-q >>>> 在压缩文件时启用静默模式(不显示压缩过程的详细信息)
-d >>>> 从现有的 ZIP 文件中删除指定的文件或目录
-u >>>> 更新(update)现有 ZIP 文件(将新的文件 或 修改后的文件 添加到 ZIP 存档中)
-m >>>> 用于移动(归档)文件到一个 ZIP 压缩文件中,并在移动后将源文件删除
-e >>>> 用于对 ZIP 压缩文件进行加密
-z >>>> 为压缩文件添加注释

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
### 1. 压缩文件夹,解决 80% 应用场景 ###
#
#
# 压缩多个文件:
$ zip -r file.zip file1 file2 ... fileN
#
# 保留层级结构压缩,并指定 ZIP 包存放位置:
$ zip -r /home/temp/test.zip /home/test
#
# 压缩指定类型的文件:
$ zip -r test.zip *.txt
#
# 压缩文件并排除指定文件(-x/--exclude):
$ zip -r test.zip /home/test -x "/home/test/test01/*"
$ zip -r test.zip /home/test --exclude "/home/test/test01/*"


# 压缩文件时不显示压缩过程的详细信息(-q):
$ zip -rq file.zip file1 file2 ... fileN


# 可以从 ZIP 存档中删除不需要的文件或目录:
$ zip -d test.zip /home/test/a.txt


# 用于更新现有的 ZIP 文件,将新的文件(添加)或修改后的文件(覆盖)更新到 ZIP 存档中:
$ zip -u test.zip b.txt


# 用于移动(归档)文件到一个 ZIP 压缩文件中,并在移动后将源文件删除:
$ zip -m test.zip a.txt b.log


# 用于对 ZIP 文件进行加密(需要设置一个解压密码)
$ zip -e file.zip file1 file2 ... fileN

# 为压缩文件添加注释:
$ zip -z test.zip
# 可通过 unzip 命令进行查看(压缩包中包含的文件):
$ zipinfo -l test.zip
$ unzip -l test.zip

[2] >>> unzip

功能描述:用来解压缩文件(.zip),以实现对文件的解包。

使用样例:

1
2
# 将 test.zip 压缩包文件解压到 /home/demo 目录下,并显示详细的解压信息:
$ unzip /home/test.zip -vd /home/demo

bzip2/bunzip2

非常类似于 gzip/gunzip,但 bzip2/bunzip2 压缩比较高,适合一些大型文件的解压缩。

[1] >>> bunzip2

功能描述: 压缩文件(File),生成 .bz2 压缩文件。

使用须知 >>> 只能压缩文件(File),不可以压缩目录(Dir),不会保留原文件。

语法格式:bzip2 [Options:v/d/-k] [File...],使用样例如下:

1
2
3
4
5
6
7
8
9
10
# 压缩文件 file,并显示命令执行过程信息:
$ bzip2 -v file
# 压缩文件 file,并显示命令执行过程信息(保留源文件):
$ bzip2 -kv file

# 检查压缩文件完整性:
$ bzip2 -vt file.gz

# 可以使用 -d 参数,对 .gz 文件进行减压:
$ bzip2 -vd test.txt

[2] >>> bunzip2

功能描述: 解压缩文件(File.bz2)

使用须知 >>> bunzip2 -r” 依然只会递归解压缩指定目录下的压缩文件(.bz2),而不会解打包(.tar)。

语法格式:bunzip2 [Options:v/k] [File...],使用样例如下:

1
2
3
4
5
# 解压 file.gz 压缩文件,并显示命令执行过程信息:
$ bunzip2 -v file.bz2

# 解压 file.gz 压缩文件,并显示命令执行过程信息(保留压缩文件):
$ gunzip -vk file.bz2

View Linux-Distr Version Info

对于诸如 RHEL、Debian、openSUSE、Arch Linux 这几种主流发行版来说,它们各自拥有不同的包管理器,以及指令工具。如果不知道使用的是哪一个发行版的系统,就无法正确使用相关的包管理器或其它工具指令。

那么,如何查看 Linux 发行版名称和版本号?!!这里提供几种查看方法 >>>>

[1] >>> 版本信息文件

/etc 目录下放置了很多记录着发行版各种信息的文件(以 release 结尾的文件),每个发行版都各自有一套这样记录着相关信息的文件。

你可以通过查看这些文件来获取发行版版本号信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
### 1. For Debian/Ubuntu ###
$ ls /etc/ | grep "release"
lsb-release
os-release

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.6 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.6 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal


### 2. For RHEL/CentOS/Fedora ###
$ ls /etc/ | grep "release"
centos-release
centos-release-upstream
os-release
redhat-release
system-release
system-release-cpe

$ cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

$ cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

此外,/proc/version 文件中也记录了 Linux 内核的版本、用于编译内核的 GCC 的版本、内核编译的时间,以及内核编译者的用户名。

1
2
$ cat /proc/version
Linux version 5.15.133.1-microsoft-standard-WSL2 (root@1c602f52c2e4) (gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.37) #1 SMP Thu Oct 5 21:02:42 UTC 2023

| ================================================== Split Line =============================================== |

[2] >>> lsb_release 命令

LSB(Linux Standard Base)是一个能打印发行版具体信息的标准库(包括发行版名称、版本号、代号等):

1
2
3
4
5
6
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal

Mini 版本的 Linux 中可能未安装有 LSB 库,显示 bash: lsb_release: command not found...。你可以安装后使用(以 CentOS 为例):

1
2
3
4
5
6
7
8
$ sudo yum -y install redhat-lsb

$ lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 7.9.2009 (Core)
Release: 7.9.2009
Codename: Core

| ================================================== Split Line =============================================== |

[3] >>> uname 命令

uname(Unix Name)是一个打印系统信息的工具(包括内核名称、版本号、系统详细信息以及所运行的操作系统等):

1
2
$ uname -a
Linux LAPTOP-SNOSCKOB 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu Oct 5 21:02:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

这里,由于是在 WSL Ubuntu 环境中使用,显示的操作系统版本是 5.15.133.1-microsoft-standard-WSL2

| ================================================== Split Line =============================================== |

[4] >>> dmesg 命令

dmesg(Display Message) 或 (Driver Message))是大多数类 Unix 操作系统上的一个命令,用于打印内核的消息缓冲区的信息:

1
2
3
4
5
6
7
8
$ dmesg | grep "Linux"
[ 0.000000] Linux version 5.15.133.1-microsoft-standard-WSL2 (root@1c602f52c2e4) (gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.37) #1 SMP Thu Oct 5 21:02:42 UTC 2023
[ 0.103553] ACPI: Added _OSI(Linux-Dell-Video)
[ 0.103553] ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio)
[ 0.103553] ACPI: Added _OSI(Linux-HPI-Hybrid-Graphics)
[ 0.110752] pps_core: LinuxPPS API ver. 1 registered
[ 0.521577] usb usb1: Manufacturer: Linux 5.15.133.1-microsoft-standard-WSL2 vhci_hcd
[ 0.529023] usb usb2: Manufacturer: Linux 5.15.133.1-microsoft-standard-WSL2 vhci_hcd

Network Communication

Linux 中的网络通信相关指令:

ping

Linux 中的 ping 指令可用于检测系统的网络连通性,其命令格式为:

1
2
3
4
5
$ ping [options] <ip/domain>

# 常用参数
-c <count> stop after <count> replies
-s <size> use <size> as number of data bytes to be sent

Example >>>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 1. ping 本地网络回环地址,不手动终止会一直 ping 下去:

$ ping localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.209 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.028 ms
64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.037 ms
^C
--- localhost ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3086ms
rtt min/avg/max/mdev = 0.028/0.083/0.209/0.073 ms

# 2. ping 4 次后终止:

ping -c 4 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.292 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.210 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.038 ms
64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.026 ms

--- localhost ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3079ms
rtt min/avg/max/mdev = 0.026/0.141/0.292/0.113 ms

# 3. 设置 ping 每次发送数据包的大小:

$ ping -c 4 -s 64 localhost
PING localhost (127.0.0.1) 64(92) bytes of data.
72 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.023 ms
72 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.025 ms
72 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.046 ms
72 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.029 ms

--- localhost ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3054ms
rtt min/avg/max/mdev = 0.023/0.030/0.046/0.009 ms

↓↓↓↓↓↓ 实际应用场景 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
9
10
11
12
# 1. ping 127.0.0.1/localhost >>> PING 本地回环地址 >>> 验证本机 TCP/IP 协议是否正常?!!

# 2. ping <localhost_ip> >>> PING 本机 IP 地址 >>> 验证本机的网络适配器(网卡)是否正常工作?!!

# 3. ping <target_pc_ip> >>> PING 局域网(同网段)内计算机 IP,不通则表明网络线路出现故障;
若网络中还包含有路由器/交换机:
1)应先 PING 路由器在本网段端口的 IP,不通则此段线路有问题;
2)若通,则再 PING 路由器在目标计算机所在网段的端口 IP,不通则是路由出现故障;
3)若通,则再 PING 目标计算机 IP 地址。
>>> 验证主机是否存在,或两台主机间网络是否通畅?!!

# 4. ping <external_ip/domain> >>> PING 网址(域名或域名映射的 IP)>>> 验证是否可以连接外网(上网)?!!

ip/ifconfig

Linux ip && ifconfig 命令类似,用于显示或设置网络设备。

ip 是 Linux 加强版的的网络配置工具,用于代替较古老的 ifconfig 命令。其中,ip 工具包含于 iproute/iproute2 包,ifconfig 包含于 net-tools 包,以解决 not found 问题。

需要注意的是 >>> 通过 ip/ifconfig 进行网卡信息的配置后,“可能” 只是临时生效(不可靠),方别进行快速连网实验。想要永久生效需要通过网络的配置文件进行设置。

下面分别来看 ip && ifconfig 的使用:


ifconfig

虽然其作为较早期版本的网络设备命令,但现在仍能看见有人在使用,你只需关注其最基本用法,将更多精力放在学习 ip 上(毕竟是新一代工具)。

↓↓↓↓↓↓ 查看网络设备信息 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 只查看激活状态的网卡信息:
$ ifconfig
# 显示所有(激活/未激活)网络设备的信息
$ ifconfig -a

# 网卡信息:
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
inet6 fe80::13ee:c8bd:93f2:ac21 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:8a:2a:7f txqueuelen 1000 (Ethernet)
RX packets 44705 bytes 66008628 (66.0 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4580 bytes 314661 (314.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

# 本地回环:
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 240 bytes 21884 (21.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 240 bytes 21884 (21.8 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

可见,当前系统中存在一块名为:enp0s3 的网卡。网卡信息说明 >>> inet 表示网卡 IP 地址;broadcast 表示广播地址;netmask 表示子网掩码;ether 表示网卡的物理(Mac)地址。

ifconfig 查看信息详细描述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
### 网卡名称(代号):
enp0s3
### 网卡的编号存在一定的规则(与其来源有关):
eno1:代表由主板 BIOS 内置的网卡;
ens1:代表由主板 BIOS 内置的 PCI-E 网卡;
enp2s0: PCI-E 独立网卡;
eth0:如果以上都不使用,则回到默认网卡名(Ethernet);
virbr0/virbr0-nic:虚拟网络接口

### 网络接入类型:
Link encap:Ethernet(以太网)

### 网卡的物理地址(MAC):
ether/HWaddr

### 网络 IP 地址
inet/inet addr
### 子网掩码
netmask/Mask
### 广播地址
broadcast/Bcast

### IPV6 地址:
inet6/inet6 addr

### 最大传输单元(网络链路帧长限制):
MTU
### 传送数据缓冲区大小
txqueuelen
### 跃点数(路由成本,通常表示到达目的地址的跳数):
Metric

### 从网络启动开始,接收包的总数/总字节数:
RX packets/bytes
### 从网络启动开始,发送包的总数/总字节数:
TX packets/bytes

### 包碰撞情况(碰撞包越多,网络越不稳定):
collisions :表示的(如果碰撞的包很多,表明你的网络不太好)

### 本机环回接口:
lo

| ================================================== Split Line =============================================== |

↓↓↓↓↓↓ 重启网卡 ↓↓↓↓↓↓

常用于配置网卡信息后,重启网卡使得配置生效:

1
2
3
4
5
# 关闭指定网卡:
$ ifconfig eth0 down

# 启动指定网卡:
$ ifconfig eth0 up

| ================================================== Split Line =============================================== |

↓↓↓↓↓↓ 配置网卡信息 ↓↓↓↓↓↓

1
2
3
4
5
# 为 eth0 网卡 配置 >>> IP 地址:
$ ifconfig eth0 192.168.1.56

# 为 eth0 网卡 配置 >>>IP 地址,子网掩码,广播地址:
$ ifconfig eth0 192.168.1.56 netmask 255.255.255.0 broadcast 192.168.1.255

| ================================================== Split Line =============================================== |

↓↓↓↓↓↓ 配置和删除 IPv6 地址 ↓↓↓↓↓↓

1
2
3
4
5
# 为 eth0 网卡设置 IPv6 地址:
$ ifconfig eth0 add 33ffe:3240:800:1005::2/ 64

# 为 eth0 网卡删除 IPv6 地址
$ ifconfig eth0 del 33ffe:3240:800:1005::2/ 64

| ================================================== Split Line =============================================== |

↓↓↓↓↓↓ 修改 MAC 地址 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
# 关闭网卡:
$ ifconfig eth0 down

# 修改 MAC 地址
$ ifconfig eth0 hw ether 00:AA:BB:CC:DD:EE

# 重新启动网卡
$ ifconfig eth0 up

ip

ip 命令更为全面复杂,其命令格式如下:

1
$ ip [OPTIONS] OBJECT {COMMAND | help }

其中,OBJECT 为常用对象(必选),其值:OBJECT={ link | addr | addrlabel | route | rule | neigh | ntable | tunnel | maddr | mroute | mrule | monitor | xfrm | token }。常用取值含义:

  • link:网络设备;
  • addr:设备上的协议地址(IP/IPv6);
  • addrlabel:协议地址选择的标签配置;
  • route:路由表条目;
  • rule:路由策略数据库中的规则。

常用 OPTIONS 取值含义可见 ip --help 中说明。

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
### 1. ip link ###
# 显示网络接口(网卡)信息
$ ip link show/list
# 开启网卡
$ ip link set eth0 up
# 关闭网卡
$ ip link set eth0 down
# 开启网卡的混合模式
ip link set eth0 promisc on
# 关闭网卡的混个模式
ip link set eth0 promisc offi
# 设置网卡队列长度
$ ip link set eth0 txqueuelen 1200
# 设置网卡最大传输单元
$ ip link set eth0 mtu 1400

### 2. ip addr ###
# 显示网卡 IP 信息
$ ip addr show/list
# 设置 eth0 网卡 IP 地址:192.168.0.1
$ ip addr add 192.168.0.1/24 dev eth0
# 删除 eth0 网卡 IP 地址
$ ip addr del 192.168.0.1/24 dev eth0

### 3. ip route ##
# 显示系统路由信息
$ ip route show/list
# 设置系统默认路由
$ ip route add default via 192.168.1.254
# 设置 192.168.4.0 网段的网关为 192.168.0.254,数据走 eth0 接口
$ ip route add 192.168.4.0/24 via 192.168.0.254 dev eth0
# 设置默认网关为 192.168.0.254
$ ip route add default via 192.168.0.254 dev eth0
# 删除 192.168.4.0 网段的网关
$ ip route del 192.168.4.0/24
# 删除默认路由
$ ip route del default
# 删除路由
ip route delete 192.168.1.0/24 dev eth0

dhclient

dhclient(Dynamic Host Configuration Protocol Client)命令,可用于从 DHCP 服务器获取 IP Address && NETMASK && GATEWAY && DNS 等网络信息,以支持让网卡动态获取网络配置。

适用于大多数 Linux 发行版:Ubuntu、Debian、Fedora、CentOS 等,可以通过安装 dhcp-client 包,以解决 not found 问题。

其命令格式如下:

1
dhclient [选项] [网络接口]

其中,网络接口是指要配置的网卡;如果不指定网络接口,会尝试为所有可用的网络接口获取动态 IP。

| ================================================== Split Line =============================================== |

下面来看 dhclient 的使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 为所有可用的网络接口获取动态 IP 地址
$ sudo dhclient

# 为指定网络接口 eth0 获取 IP 地址
$ sudo dhclient eth0
# 为指定网络接口 eth0 获取 IP 地址,并显示日志信息:
$ sudo dhclient -v eth0

# 释放指定 eth0 网络接口的 IP 地址
$ sudo dhclient -r eth0


# 不等待 DHCP 服务器的响应
sudo dhclient -nw eth0

# 指定 DHCP 服务器的地址
$ sudo dhclient -s 192.168.1.2 eth0

| ================================================== Split Line =============================================== |

↓↓↓↓↓↓ 问题描述 ↓↓↓↓↓↓

DHCP 网络模式下,服务器重启后网络接口(网卡)无法动态获取 IP。

原因分析:

  • NetworkManager 未开启自启动,导致 dhclient 进程未运行;
  • 网卡设备未纳入 NetworkManager 管理导致

↓↓↓↓↓↓ 解决方法 ↓↓↓↓↓↓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 1. 确认 dhclient 是否运行:
$ ps -ef |grep dhclient |grep -v grep


# 2. 如果未找到 dhclient 进程,则确认 dhclient 进程未运行。
# 执行以下命令,继续排查 NetworkManager 是否运行:
$ systemctl status NetworkManager

# 2.1 如果 NetworkManager 的状态为 Active: inactive (dead),则 NetworkManager 未启动。
# 执行以下命令,检查该服务是否开机自启:
$ systemctl is-enabled NetworkManager
# 结果为 disabled 则确认为 NetworkManager 未设置开机自启导致。执行以下命令进行恢复:
$ systemctl enable NetworkManager && systemctl start NetworkManager

# 2.2 如果 NetworkManager 的状态为 Active: active (running)
# 执行以下命令查看网卡设备是否被 NetworkManager 管理:
$ nmcli device status
# 如果显示该网卡为的 STATE 为 unmanaged,则该网卡设备未被 NetworkManager 管理。执行以下命令进行恢复:
$ nmcli device set eth0 managed yes


# 3. 如果找到 dhclient 进程:
$ ps -ef |grep dhclient |grep -v grep
root 1096 965 0 21:10 ? 00:00:00 /sbin/dhclient -d -q -sf /usr/libexec/nm-dhcp-helper -pf /var/run/dhclient-enp0s3.pid -lf /var/lib/NetworkManager/dhclient-6620a662-540c-478d-bd15-9b47ed8ffec6-enp0s3.lease -cf /var/lib/NetworkManager/dhclient-enp0s3.conf enp0s3
# 检查 2.2

# 4. 执行以下命令重启 NetworkManager:
$ systemctl restart NetworkManager

# 5. 执行以下命令查看 ip 是否已经获取:
$ ip addr

write/wall

write 命令用于向当前系统的另一个用户(必须登陆)发送信息,以 CTRL+D 作为结束;

wall 命令用于向当前系统的所有用户(必须登陆)广播信息/文件,以 CTRL+D 作为结束;


System Resource Monitoring

Linux 系统中各种资源(Disk & Memory & CPU & Process & Ports)的监控和管理:

df/du

df(Disk Free)&& du(Disk Usage),都是用来监控文件所占用的磁盘空间大小。

[1] >>> df

df 是以磁盘分区为单位查看文件系统,以监控硬盘已使用了多少空间,还剩下多少空闲空间等信息。

1
2
3
4
5
6
7
8
9
10
$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 903M 0 903M 0% /dev
tmpfs 919M 0 919M 0% /dev/shm
tmpfs 919M 9.2M 910M 2% /run
tmpfs 919M 0 919M 0% /sys/fs/cgroup
/dev/mapper/centos-root 8.0G 5.6G 2.5G 70% /
/dev/sda1 1014M 238M 777M 24% /boot
tmpfs 184M 12K 184M 1% /run/user/42
tmpfs 184M 0 184M 0% /run/user/1000

df 的使用较为简单,明确了磁盘中磁盘分区的使用容量后,就可以使用下面的 df 命令来具体分析:占满磁盘的都是什么文件?!!

| ================================================== Split Line =============================================== |

[2] >>> du

语法格式:du [Options] [FILE/Dir]...,其常用选项如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
-a                              >>>> 显示目录中所有文件以及目录大小

-h >>>> 以 Kb、Mb 、Gb 等人类易读(human)的单位显示大小(1024)
--si >>>> 以 Kb、Mb 、Gb 等人类易读(human)的单位显示大小(1000)

-c >>>> 显示目录大小,并额外显示总占用量
-s >>>> 显示目录总大小

-d(--max-depth=N) >>>> 指定查看目录的深度
--time >>>> 显示目录下最近修改文件的时间

-t(--threshold=SIZE) >>>> 过滤掉小于 SIZE 大小的文件以及目录
--exclude=PATTERN >>>> 过滤与 PATTERN 模式匹配的文件名或者目录名

常用使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 显示指定目录下,所有目录大小:
$ du temp/
# 显示指定目录下,所有目录以及目录下文件的大小(默认单位:KB):
$ $ du -a temp/


# 以人易读的方式,显示指定目录下所有目录大小:
#
# 1 MB = 1024 KB
$ $ du -h temp
$ du -ah temp
#
# 1 MB = 1000 KB
$ du --si temp
$ du -a --si temp


# 显示所有目录大小,并额外显示总占用量
$ $ du -ch temp


# 显示指定深度(depth)的目录大小:
$ du -d 0 temp/
8.0K temp/
$ du -d 1 temp/
4 temp/valid
0 temp/test
8 temp/
#
$ du -ach --max-depth=1 temp
4.0K temp/valid
0 temp/test
0 temp/TEST.txt
4.0K temp/test.txt
8.0K temp
8.0K total


# 按照文件大小过滤
$ du -ah -t 2k temp/
$ du -ah -t 8M temp/


# 按照目录名或文件名过滤后,显示剩余文件所占磁盘容量:
$ du -a --exclude=*.txt temp/


### 占满磁盘的都是什么文件?!! ###
#
#
# 1. 当前目录下文件从大到小排序
$ du -sh temp/* | sort -hr
#
# 2. 当前目录以及子目录从大到小排序
$ du -ah temp/* | sort -hr
#
# 3. 磁盘占用最大的三个目录以及子目录
$ $ du -ah temp/* | sort -hr | head -n 3

free

free(空闲),用来监控操作系统中内存的使用情况,包括物理内存(Memory)&& 交换内存(Swap)&& 内核缓冲区内存(buff/cache)。

语法格式:free [Options: h/s],其常用选项如下:

1
2
-h                                 >>>> 以 Kb、Mb 、Gb 等人类易读(human)的单位显示大小(1024)
-s [seconds] >>>> 动态监控,每 [seconds] 秒显示一次,直至 Ctrl + c 退出

示例演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ free -h
total used free shared buff/cache available
Mem: 1.8G 373M 1.1G 11M 318M 1.3G
Swap: 1.0G 0B 1.0G

$ $ free -h -s 2
total used free shared buff/cache available
Mem: 1.8G 374M 1.1G 11M 318M 1.3G
Swap: 1.0G 0B 1.0G

total used free shared buff/cache available
Mem: 1.8G 374M 1.1G 11M 318M 1.3G
Swap: 1.0G 0B 1.0G

free 命令输出信息字段含义说明:

1
2
3
4
5
6
7
8
9
Mem Line                               >>>> 内存(Memory)的使用情况
Swap Line >>>> 交换空间(Swap)的使用情况

total >>>> 显示系统总的可用 物理内存 和 交换空间 大小
used >>>> 显示已经被使用的 物理内存 和 交换空间
free >>>> 显示还有多少剩余 物理内存 和 交换空间 可用
shared >>>> 显示被共享使用的 物理内存 大小
buff/cache >>>> 显示被 buffer 和 cache 使用的物理内存大小
available >>>> 显示还可以被 应用程序 使用的 物理内存 大小

| ================================================== Split Line =============================================== |

👇👇👇 关于 Buffer/Cache 👇👇👇

思考一下 >>> buffer 和 cache 是两种类型的内存,但 free 命令为什么会把它们放在一起呢?!!

[1] >>> buffer

要理解 buffer(buffer cache)缓冲区,必须明确另外两个概念:”扇区” 和 “块”。

扇区是设备的最小寻址单元,也叫 “设备块”。块是操作系统中文件系统的最小寻址单元,也叫 “文件块” 或 “I/O 块”。每个块(Block)包含一个或多个扇区,但大小不能超过一个页面(Page),所以一个页可以容纳一个或多个内存中的块。

当一个块被调入内存时,它要存储在一个缓冲区中。每个缓冲区与一个块对应,它相当于是磁盘块在内存中的表示。

buffer cache 只有块的概念而没有文件的概念,它只是把磁盘上的块直接搬到内存中而不关心块中究竟存放的是什么格式的文件。

[2] >>> cache

cache(page cache)页高速缓存,是内核实现的磁盘缓存。它主要用来减少对磁盘的 I/O 操作。具体地讲,是通过把磁盘中的数据缓存到物理内存中,把对磁盘的访问变为对物理内存的访问。页高速缓存缓存的是内存页面。缓存中的页来自对 普通文件、块设备文件(buffer cache)和 内存映射文件 的读写。

  • 页高速缓存对普通文件的缓存 >>> 当内核要读一个文件(比如 /tmp/test)时,它会先检查这个文件的数据是不是已经在 Page Cache 中了:如果在(缓存命中),就放弃访问磁盘,直接从内存中读取;如果数据不在缓存中(未命中缓存),此时内核就要调度块 I/O 操作从磁盘去读取数据,然后内核将读来的数据放入 Page Cache 中。

  • 页高速缓存对块设备文件的缓存 >>> 就是 buffer cahce,独立的磁盘块通过缓冲区也被存入了页高速缓存(缓冲区最终是由页高速缓存来承载的)。

可以发现 >>> 无论是缓冲区还是页高速缓存,它们的实现方式都是一样的(缓冲区只不过是一种概念上比较特殊的页高速缓存)。

| ================================================== Split Line =============================================== |

👇👇👇 关于 Swap Space 👇👇👇

Swap Space(交换空间),可以是磁盘上的一个独立分区,也可以是一个文件。

当系统物理内存吃紧时,Linux 会将内存中不常访问的数据保存到 Swap 上,这样系统就有更多的物理内存为各个进程服务;而当系统需要访问 Swap 上存储的内容时,再将 Swap 上的数据加载到内存中,这就是常说的换出和换入。

交换空间可以在一定程度上缓解内存不足的情况,但由于需要读写磁盘,所以性能相较于内存读取较低~~~


top

top 是 Linux 中最常用的系统性能分析工具,能够实时显示系统中各个进程的资源占用情况。

其语法格式为 ps [Options:d/b/n/p],常用选项如下:

1
2
3
4
5
6
-d number                              >>>> 表示页面刷新一次的时间间隔 (default=5s)

-b >>>> 表示以批次(batch)的方式执行 top
-n >>>> 与 -b 配合使用,表示需要进行几次(几个批次)输出

-p >>>> 指定特定的 pid 进程号进行观察

top 命令显示的页面还可以输入以下按键执行相应的功能(注意大小写):

1
2
3
4
5
6
7
8
9
10
?                                      >>>> 显示可执行命令的帮助信息

P >>>> 以 CPU 的占用量排序显示(默认)
M >>>> 以 Memory 的使用资源排序显示
N >>>> 以 PID 排序显示
T >>>> 由进程的使用时间累计排序显示

k >>>> 给某个 PID 一个 kill 信号,可以用来杀死进程(9)
r >>>> 给某个 PID 重新定制一个 nice 值(优先级)
q >>>> 退出 top(Ctrl + c)

top 各输出参数含义:

[1] >>> top 前五条信息解释

top - 14:32:58 up 2:24, 1 user, load average: 0.00, 0.00, 0.00

1
2
3
4
14:32:58                               >>>> 表示当前时间
up 2:24 >>>> 系统远行时间(格式为时:分)
1 user >>>> 当前登陆用户数
load average: 0.00, 0.00, 0.00 >>>> 系统负载(任务队列的平均长度),分别为 1分钟 & 5分钟 & 15分钟前到当前的平均值

Tasks: 120 total, 1 running, 87 sleeping, 0 stopped, 0 zombie

1
2
3
4
5
Tasks: 120 total                       >>>> 系统中进程总数
1 running >>>> 正在运行的进程数
87 sleeping >>>> 睡眠的进程数
0 stopped >>>> 停止的进程数
0 zombie >>>> 僵尸进程数

%Cpu(s): 0.0 us, 0.7 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st

1
2
3
4
5
6
7
8
0.0%us                                 >>>> 用户空间占用 CPU 百分比
0.7 sy >>>> 内核空间占用 CPU 百分比
0.0 ni >>>> 用户进程空间内改变过优先级的进程占用 CPU 百分比
99.0 id >>>> 空闲 CPU 百分比
0.0 wa >>>> 等待输入输出的 CPU 时间百分比
0.0 hi >>>> 硬中断(Hardware IRQ)占用 CPU 的百分比
0.3 si >>>> 软中断(Software Interrupts)占用 CPU 的百分比
0.0 st >>>> 用于有虚拟 CPU 的情况,用来指示被虚拟机偷掉的 CPU 时间

KiB Mem : 2041020 total, 1587728 free, 159148 used, 294144 buff/cache

1
2
3
4
2041020 total                          >>>> 物理内存总量
1587728 free >>>> 空闲内存总量
159148 used >>>> 已使用的物理内存总量
294144 buff/cache >>>> 内核缓存的内存量

KiB Swap: 998396 total, 998396 free, 0 used. 1717548 avail Mem

1
2
3
4
998396 total                           >>>> 交换区总量
998396 free >>>> 空闲交换区总量
0 used >>>> 已使用的交换区总量
1717548 avail Mem >>>> 应用程序可用交换空间容量

| ================================================== Split Line =============================================== |

[2] >>> 进程信息字段含义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PID                                    >>>> 进程 ID
USER >>>> 进程所有者的用户名

PR >>>> 进程优先级
NI >>>> nice 优先级值(负值表示高,正值表示低优先级)

VIRT >>>> 进程使用的虚拟内存总量(KB),VIRT = SWAP + RES
RES >>>> 进程使用的、未被换出的物理内存大小(KB),RES = CODE + DATA
SHR >>>> 共享内存大小(KB)
S >>>> 进程状态(D/R/S/T/ZW/X/l)
%CPU >>>> 上次更新到现在的 CPU 时间占用百分比
%MEM >>>> 进程使用的物理内存百分比
TIME+ >>>> 进程使用的 CPU 时间总计(单位 1/100 秒)
COMMAND >>>> 命令名/命令行

/netstat


mount\wget\curl\

ssh\scp


Process Management

Linux 中的各种进程管理命令:

ps

ps(Process Status),是 Linux 最常用的进程监控命令,可以查看系统中所有运行进程的详细信息。

首先来查看一下 man ps 中的描述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PS(1)                                                                                User Commands                                                                                PS(1)

NAME
ps - report a snapshot of the current processes.

SYNOPSIS
ps [options]

DESCRIPTION
ps displays information about a selection of the active processes. If you want a repetitive update of the selection and the displayed information, use top(1) instead.

This version of ps accepts several kinds of options:

1 UNIX options, which may be grouped and must be preceded by a dash.
2 BSD options, which may be grouped and must not be used with a dash.
3 GNU long options, which are preceded by two dashes.

描述(DESCRIPTION)中可以看到,Linux 中 ps 支持 UNIX、BSD、GUN 三种风格的语法:

1
2
3
UNIX 风格                          >>>> UNIX 选项可以组合在一起,并且选项前必须有 “-” 连字符
BSD 风格 >>>> BSD 是 Unix 的一个分支,选项可以组合在一起,但是选项前不能有 “-” 连字符
GNU 风格 >>>> GUN Linux 长选项,选项前有两个 “-” 连字符

多种风格语法要归咎于 UNIX 悠久的历史和庞大的派系(不同的 Linux 发行版上,ps 命令的语法各不相同),Linux 融合各种不同的风格,以兼顾习惯在不同的 Linux 发行版上使用 ps 命令的用户。

其语法格式为 ps [Options],常用选项如下:

1
2
3
4
5
6
7
8
9
a                                   >>>> 显示终端上的所有进程(包括其他用户的进程)
u >>>> 显示进程的归属用户及内存的使用情况
x >>>> 显示没有控制终端的进程

-e >>>> 显示所有进程
-l >>>> 长格式显示更加详细的信息
-f >>>> 全格式列表(会打印详细命令参数);当与 -L 一起使用时,将添加 NLWP(线程数)和 LWP(线程 ID)列 <<< Light Weight Process(轻量级进程)

-u >>>> 显示指定用户的所有进程

ps 命令格式非常多,这里 推荐记忆几个固定选项组合(足够日常使用)

1
2
3
4
5
ps aux                              >>>> 可以查看系统中所有的进程

ps -le >>>> 可以查看系统中所有的进程,而且还能看到进程的父进程的 PID 和进程优先级
ps -ef >>>> 同 le 相似
ps -l >>>> 只能看到当前 Shell 产生的进程

| ================================================== Split Line =============================================== |

使用实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 查看所有进程时,配合 more && head 命令进行查看:
$ ps aux | more
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
#
$ ps -ef | head -n 5
UID PID PPID C STIME TTY TIME CMD
#
$ ps -el | head -n 5
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD


# 查看当前 Shell 登录产生的进程
$ $ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 1889 1888 0 80 0 - 29082 do_wai pts/0 00:00:00 bash
0 R 1000 2233 1889 0 80 0 - 38338 - pts/0 00:00:00 ps
#
# 可见,当前从 pts/0 虚拟终端登录,只产生了两个进程:一个是登录之后生成的 Shell:bash;另一个是正在执行的 ps 命令。


# 查找特定名称的进程信息
$ ps -ef | grep ssh
$ ps -aux | grep ssh
$ ps aux | grep ssh
root 1290 0.0 0.2 112924 4316 ? Ss 12:09 0:00 /usr/sbin/sshd -D
root 1831 0.0 0.3 161000 5740 ? Ss 12:10 0:00 sshd: centos [priv]
centos 1888 0.1 0.1 161000 2668 ? S 12:10 0:00 sshd: centos@pts/0
centos 2293 0.0 0.0 112816 972 pts/0 S+ 12:21 0:00 grep --color=auto ssh
#
# grep -v grep 可以去除包含 grep 的进程行,只保留特定进程的相关信息
$ ps -ef | grep ssh | grep -v grep
root 1290 1 0 12:09 ? 00:00:00 /usr/sbin/sshd -D
root 1831 1290 0 12:10 ? 00:00:00 sshd: centos [priv]
centos 1888 1831 0 12:10 ? 00:00:01 sshd: centos@pts/0
#
# 查找特定 PID 的进程信息
$ ps -p <process_id> -lf
#
# 显示指定用户的进程
$ $ ps -u root


# 查看进程排序后的信息(以第三列 >>> CPU 资源的使用量,进行排序):
$ ps -aux | sort -nk 3

ps 命令输出信息字段含义说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
USER          >>>> 进程所有者的用户名
PID >>>> 进程ID(Process ID)
START >>>> 进程激活时间
%CPU >>>> 进程的cpu占用率
%MEM >>>> 进程使用内存的百分比
VSZ >>>> 进程使用的虚拟内存大小,以K为单位
RSS >>>> 驻留空间的大小。显示当前常驻内存的程序的K字节数。
TTY >>>> 与进程关联的终端(tty)
STAT >>>> 进程状态,包括下面的状态:
D 不可中断 Uninterruptible sleep (usually IO)
R 正在运行,或在队列中的进程
S 处于休眠状态
T 停止或被追踪
Z 僵尸进程
W 进入内存交换(从内核2.6开始无效)
X 死掉的进程
< 高优先级
N 低优先级
L 有些页被锁进内存
s 包含子进程
\+ 位于后台的进程组;
l 多线程,克隆线程

TIME >>>> 进程使用的总CPU时间
COMMAND >>>> 被执行的命令行
NI >>>> 进程的优先级值,较小的数字意味着占用较少的CPU时间
PRI >>>> 进程优先级。
PPID >>>> 父进程ID
WCHAN >>>> 进程等待的内核事件名

jobs/fg/bg/&/kill/disown/nohup

在 Linux 服务器上运行程序,通过会通过一个连接到 Linux Server 的 Shell 中启动程序(交互进程),此时系统中会创建一个运行于前台的进程。而为了避免其它用户因操作失误使得我们的进程被关闭,我们希望可以将进程转到后台运行。

这就涉及到 Linux 系统的任务(Job)/进程(Process)管理了,主要用到:jobs/fg/bg/&/kill/disown/nohup 等相关的命令。

这里,我们将通过一个具体的任务,来讲解 Linux 系统中的任务(Job)/进程(Process)管理命令。

我们会使用名为 running.sh 的 shellscript 作为演示程序,其功能是每隔 1 秒输出一次当前日期与时间:

1
2
3
4
5
6
7
$ cat running.sh
#!/bin/bash
while True;
do
date +"PID[$$] : the current date and time is %F %T"
sleep 1s
done

其中,方括号内的 $$ 用于获取当前 shellscript 运行的进程 ID。


jobs 任务管理指令

首先,尝试运行(启动)一下 running.sh:

1
2
3
4
$ bash running.sh
PID[5322] : the current date and time is 2024-03-17 16:17:36
PID[5322] : the current date and time is 2024-03-17 16:17:37
PID[5322] : the current date and time is 2024-03-17 16:17:38

像上面这样启动的脚本,被称为 “前台任务(Foreground Job)”。它会独占 Shell 窗口,一直输出日志信息,只有运行结束或者手动挂起/终止,才能再执行其他命令。

| ================================================== Split Line =============================================== |

[1] >>> Ctrl + C && CTRL + Z

此时想要执行其他命令,只需按下键盘上的 Ctrl + c 即可终止程序执行(kill)。如果你不想结束程序运行,也可以通过 Ctrl + z 让程序暂停运行(halt):

1
2
3
4
5
PID[5322] : the current date and time is 2024-03-17 16:17:42
PID[5322] : the current date and time is 2024-03-17 16:17:43
PID[5322] : the current date and time is 2024-03-17 16:17:44
^Z
[1]+ Stopped bash running.sh

这时屏幕上停止了日志信息输出,Shell 重新处于交互状态,可以自由输入命令,尝试输入如下命令:

1
2
3
4
5
6
7
8
# jobs 命令说明:
# jobs >>>> 显示所有任务
# -l >>>> 显示进程号
# -lr >>>> 仅显示运行状态(Running)的任务
# -ls >>>> 仅显示停止状态(Stoped)的任务
#
$ jobs -l
[1]+ 5322 Stopped bash running.sh

其中,[1] 表示任务 ID;数字 5322 为当前启动进程的进程号( PID );Stopped 为任务状态;bash running.sh 为任务名(进程名)。

再来查看一下当前 Stopped 任务状态所对应进程的状态(T >>> 停止):

1
2
3
$ ps -lf -p 5322
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
0 T centos 5322 1889 0 80 0 - 28321 do_sig 16:17 pts/0 00:00:00 bash running.sh

事实上,此时(Ctrl + z),之前前台运行的任务已被移至后台暂停,变为了 “后台任务(Background Job)”,程序不再继承标准输入(stdin)了,这也就解释为什么 Shell 中又支持输入了。

| ================================================== Split Line =============================================== |

[2] >>> fg/bg %jobid

命令 fg %jobid 可以将后台中任务 ID 为 jobid 的进程调至前台继续运行;如不加 jobid,则操作最近一个被放入后台的任务。

bg %jobid 命令是唤醒后台中任务 ID 为 jobid 的暂停进程,让其继续执行。如不加 jobid,则唤醒最近一个被暂停的后台任务。

回到上面的示例,bash running.sh 已经成为一个后台任务并被暂停了,重新唤醒一下它:

1
2
3
4
5
6
$ bg 1
[1]+ bash running.sh &
[centos@localhost temp]$ PID[5322] : the current date and time is 2024-03-17 17:40:36
PID[5322] : the current date and time is 2024-03-17 17:40:37
PID[5322] : the current date and time is 2024-03-17 17:40:38
PID[5322] : the current date and time is 2024-03-17 17:40:39

这时会先输出一句 [1]+ bash running.sh &,其中 & 表示工作 ID 为 1 的 bash running.sh 在后台运行。

虽然后台任务不再继承标准输入,但其仍然继承标准输出(Stdout)和标准错误(Stderr),后台任务的所有输出依然会同步地在 Shell 下显示。

虽然 Shell 终端中一直有输出,但 此时 Shell 处于交互状态(interactive),可以执行其它命令或程序。此时,输入命令或执行其它程序非常难受(后台程序不断的在屏幕上输出日志信息),但只要正确输入,就不会有问题 。

你可以通过 fg 命令将其调入前台:

1
2
3
4
5
$ fg
bash running.sh
PID[6432] : the current date and time is 2024-03-17 17:57:41
PID[6432] : the current date and time is 2024-03-17 17:57:42
PID[6432] : the current date and time is 2024-03-17 17:57:43

其中,先输出一句 bash running.sh,表明程序已经来到前台运行。

↓↓↓↓↓↓ 需要注意 ↓↓↓↓↓↓

后台任务不断的在屏幕上输出日志信息,可能会给你一种错觉:想通过 Ctrl + c && Ctrl + z 终止或挂起后台程序,以阻止其输出。

后台程序会忽略 Ctrl + cCtrl + z 发出的终止或挂起信号(SIGNAL)。

| ================================================== Split Line =============================================== |

[3] >>> 输出重定向

上面 running.sh 放在后台运行,不断的在屏幕上输出日志信息。虽然方便我们观察程序输出,但防碍了继续利用当前 Shell 进行工作;即使当前不进行其它工作,对于长时间的 Shell 连接输出也容易出现问题。

此时,可以使用重定向命令,改变日志信息输出位置将其写到文件里面去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 将标准输出 1 定向输出到 file.out,标准错误输出 2 定向输出到 file.err
$ bash running.sh 1> file.out 2> file.err

# 或者将标准输出 1 与标准错误输出 2 合并定向到 file.all
$ bash running.sh 1> file.all 2>&1

# 只把标准输出 1 定向输出到 file.out,标准错误输出 2 还是保持输出到屏幕
$ bash running.sh 1> file.out

# 如果重定向输出 > 符号前没有加描述符,默认为标准输出 1
$ bash running.sh > file.out

# 重定向输出到 /dev/null(/dev/null 就像一个无底洞,可以无限往里面扔东西,坏处就是程序输出了啥也不知道)
$ bash running.sh > /dev/null 2>&1

关于输出重定向更详细的说明和使用,请参见【一文解析 Linux 中的文件描述符与输入输出重定向】中描述,这里由于篇幅原因不进行赘述!!!


Shell Tips

Shell 是内核之上,负责 Linux 内核进行交互的工具,也就是我们常说的命令行窗口。常用的 Shell 命令窗口有: bash(Bashell) && zsh(ZShell)&& csh …

| ================================================== Split Line =============================================== |

AutoCompletion & CMD History

Auto Completion(自动补全),允许用户输入系统命令 && 文件名 起始的若干字符后,<Tab> 键自动补全命令 && 文件名。

大多数 Linux 系统中,Bash 自动补全插件已经预先安装了。如果系统中没有预先安装,你可以使用以下命令进行安装:

1
2
3
4
5
# For Debian/Ubuntu
$ sudo apt-get install bash-completion

# For CentOS/RHEL
$ sudo yum install bash-completion

Command History(Command History),则允许用户浏览先前执行过的命令,并且通过 <↑、↓> 键重新调用它们。


Command Alias

命令别名(Command Alias)就是为一条命令定义另一个名称,执行这个新的名称就相当于执行这条命令。

命令别名(Command Alias)主要是针对复杂、需频繁使用的命令,以简化其调用。

你可以通过如下命令查看当前用户(root)设置的所有命令别名:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost temp]# alias -p
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

↓↓↓↓↓↓ 如何设置/删除命令别名?!! ↓↓↓↓↓↓

命令别名设置非常简单,其格式为:

1
alias [别名]=[需要别名的命令]

需要注意 >>>> 等号两边不要空格,若命令包含空格,则一定要用单引号对 ‘’ 引起来。假设为 ls -al 设置别名 lal,Shell 中执行如下:

1
$ alias lal='ls -al'

删除别名也非常简单,Shell 中执行如下:

1
2
3
$ unalias lal
$ lal
bash: lal: command not found...

| ================================================== Split Line =============================================== |

通过上面的方法设置命令别名后,只在当前 Shell 中生效。一旦 Shell 重启后就无法使用了…

↓↓↓↓↓↓ 使命令别名永久生效 ↓↓↓↓↓↓

如果想要文件永久生效,需要将上述别名命令写到 bashrc 用户 Shell 配置文件中,详细如下:

1
2
3
/etc/bashrc                    >>>> 适用于所有用户
/root/.bashrc >>>> 适用于超级管理员用户(root)
/home/[username]/.bashrc >>>> 适用于一般用户(username)

需要注意 >>>> rc(run commands)结尾的配置文件(如:.bashrc/.vimrc),是特定程序每次启动时自动运行的脚本文件。

不要将设置永久生效别名的命令写到 /etc/profile 文件中,参看其文件说明:

1
2
3
4
5
6
7
8
9
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.

关于 /etc/profile 配置文件主要用于配置系统环境变量(Java & Python…)和启动程序相关。


I/O Redirection


Author

Waldeinsamkeit

Posted on

2015-02-01

Updated on

2024-03-17

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.

Comments

You forgot to set the shortname for Disqus. Please set it in _config.yml.