# 一、Linux常用命令操作符

## 1.内部命令

> shell（壳程序）是用户和操作系统内核之间的接口，提供了一个让用户输入命令并接受结果的交互环境

- 集成在shell中，由shell自带实现，直接在shell中执行，**不需要启动额外的程序**
- 执行速度快，不涉及磁盘查找和新进程创建。
- 通常是和**shell功能紧密结合**的命令，比如环境变量，流程控制等。

例子

```
cd       # 改变当前目录
pwd      # 显示当前路径
echo     # 输出
export   # 设置环境变量
alias    # 设置命令别名
history  # 显示命令历史
```

## 2.外部命令

- **存放在文件系统里的一个可执行文件**（通常在/bin、/sbin、/usr/bin等目录）
- 执行时、shell会fork一个子进程，然后调用该可执行文件。
- 可以独立于shell存在

```
ls      # 列目录 (/bin/ls)
cat     # 查看文件内容 (/bin/cat)
grep    # 文本搜索 (/bin/grep)
vim     # 编辑器 (/usr/bin/vim)
```

**总之，内部命令和外部命令的最大区别，就是是否对应系统上的一个具体的文件**

## 3.ls命令

作用：显示当前目录下的内容

```
ls
```

- `-h`选项：以人类可读的形式展示，需要配合`-l`选项使用

- `-l`选项：以列表的形式列出内容

- `-a`选项：展示所有内容，包括隐藏的内容
  
  > linux中隐藏文件以.开头，普通使用ls看不到，只有使用-a选项才能看到

## 4.cd命令

作用：切换目录

```
cd 目标目录
```

- 绝对路径：以根目录`/`为起点，比如`/var/spool`,指的是根目录`/`下的子目录var中的spool目录
  
  例子：移动到/var/spool目录下
  
  ```
  cd /var/spool
  ```

- 相对路径：以当前工作目录为起点，在开头不使用`/`，会更便捷

## 5.cp 命令

作用：复制文件或目录

```
cp 源 目的
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-21-04-image.png)

`-r`是用来复制目录，可以级联复制目录（目录和子目录中的文件全部按结构复制）

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-21-25-image.png)

## 6.mv命令

作用：移动一个文件或目录

```
mv 源 目的
```

- mv命令可以用来更改文件或者目录的名称
  
  ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-22-46-image.png)

## 补充：虚拟机网络模式

NAT模式

桥接模式

仅主机模式

# 二、Linux文件管理

## <1>查看文件

### 1.more

作用：进入一个交互式界面查看文件内容

用法:

```
more 选项 文件
```

例子：

```
more /etc/passwd
```

流程：more在读取文件时，默认已经加载文件的全部内容。

more 命令的执行会打开一个交互界面，下面是一些常用交互命令：

| 回车键   | 向下移动一行。        |
| ----- | -------------- |
| d     | 向下移动半页。        |
| 空格键   | 向下移动一页。        |
| b     | 向上移动一页。        |
| / 字符串 | 搜索指定的字符串。      |
| :f    | 显示当前文件的文件名和行号。 |
| q 或 Q | 退出 more。       |

### 2.less

作用：分页查看文件内容，进入交互式界面

用法：

```
less 选项 文件
```

流程：不是加载整个文件，而是一点一点进行加载，相对而言，读取大文件时，效率比较高。

| 回车键   | 向下移动一行。        |
| ----- | -------------- |
| d     | 向下移动半页。        |
| 空格键   | 向下移动一页。        |
| b     | 向上移动一页。        |
| / 字符串 | 搜索指定的字符串。      |
| :f    | 显示当前文件的文件名和行号。 |
| q 或 Q | 退出 less        |

### 3.head

作用：查看文件的开头部分，默认查看文件前10行

用法：

```
head 选项 文件
```

选项：

- `-n` 指定查看的行数
  
  ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-26-19-image.png)

### 4.tail

作用：查看文件尾部的内容，默认显示末尾10行

用法：

```
tail 选项 文件
```

选项：

- `-n` 指定查看的行数

- `-f`动态显示文件内容，**监控文件内容是否有新增**
  
  ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-27-49-image.png)

### 5.wc

作用：显示文件的行、单词与字节统计信息

用法：

```
wc 选项 文件
```

选项：

- `-l`显示行数

- `-c` 显示字节数

- `-w` 显示单词数
  
  ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-28-51-image.png)

### 6.du

> 问题：为什么du显示的使用空间，和ls -lh 显示的文件大小不一样

作用：查看文件使用的空间

用法：

```
du 选项 文件
```

选项：

- `-h`以人类可读的格式显示，单位为k、m、g为单位，如果不写，默认单位为k

- `-s`显示总容量，针对于目录，不加-s会列出目录中每一项的大小，加上-s会直接列出目录中项目的合计大小
  
  ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-29-51-image.png)

### 7.df

作用：显示磁盘分区上的可使用空间，默认单位为kb

用法：

```
df 选项
```

选项：

- `-h`以人类可读的形式输出

例子：

```
df -h
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-30-40-image.png)

### 8.echo

作用：打印输入的参数

用法：

```
echo 文本
```

- 将输入内容写入到文件中，配合`\>`输出重定向符号使用
  
  ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-31-26-image.png)
  
  将内容追加到文件中，配合`\>\>`追加重定向使用
  
  <img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-20-17-32-37-image.png" title="" alt="" width="782">

### 9.tree

windows和linux中都存在的一个命令

作用：将文件以树的形式列出来

```
yum -y install tree
```

### 10.grep

作用：在文件中查找包含目标关键词的行，并输出

用法：

```
grep 目标关键词 目标文件
```

选项：

- `-n` 显示行号（筛选出的行，在目标文件中的行号）

- `-i` 忽略大小写

- `-v` 输出没有匹配到的行

- `-r`可以在目录递归匹配所有文件的内容
  
  ```
  grep -i  -r -n ftp ./
  ```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-38-50-image.png)

## <2>管道符

管道符：`|`

作用：管道是一种通信机制，通常用于进程间的通信。它表现出来的形式**将前面每一个进程的输出（stdout）直接作为下一个进程的输入（stdin）。

cat 2.txt | grep -i ftp

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-40-51-image.png)

**管道符可以嵌套**

- 筛选文件名中带txt的文件
  
  ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-41-33-image.png)

## <3>打包和压缩

- 打包：把多个文件或目录集合成一个文件，集合成的文件的大小是多个文件总和。
- 压缩：把多个文件或目录集合成一个文件，但是该文件所占磁盘空间的大小，比所有文件的总和要更小。

**tar打包**

命令：tar

作用：将多个文件打包成一个文件

用法：

```
tar [选项] [打包后的文件名] [要打包的文件或目录]
```

> 选项可以不加上`-`

选项：

#### 打包

- `-c` 创建(create)打包文件

- `-v` 显示打包过程

- `-f` 指定打包的文件名 , **此选项必须要加(打包解包都要加)**

#### 解包

- `-x` 解包
- `-t` 查看tar文件中包含哪些文件

#### 常用命令

- 打包常用命令
  
  ```
  tar -cvf 123.tar 1.txt 2.txt 3.txt
  ```

- 解包常用命令
  
  ```
  tar -xvf 123.tar
  ```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-17-47-10-image.png)

## <4>打包并压缩

命令：tar

选项：

- `-z` 压缩成gzip格式
- `-j` 压缩成bz2格式
- `-J` 压缩成xz格式

**常用命令**

- 打包并压缩

```
tar -zcvf 123.tar.gz  1.txt 2.txt 3.txt 
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-18-30-20-image.png)

- 解压并解包

```
tar -zxvf 123.tar.gz
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-18-30-47-image.png)

## <5>zip压缩和解压

- 安装zip

```
yum -y install zip
```

作用：创建一个zip格式的压缩包

用法：

```
zip 压缩后的文件名 目标1 目标2 目标3 ....
```

压缩

```
zip 123.zip 1.txt 2.txt 3.txt
```

解压

```
unzip 123.zip
```

选项： `-d` 指定要解压到哪个目录

# 三、Linux用户管理

## <1>查看用户和组

### 1.查看/etc/passwd文件

- 可以查看用户基本信息

```
cat /etc/passwd
```

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-20-18-44-20-image.png" title="" alt="" width="544">

**/etc/passwd存储用户信息的文件含义如下**

<img title="" src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-20-18-45-14-image.png" alt="" width="542">

### 2.查看/etc/group文件

- 可以查看用户组的信息

```
cat /etc/group
```

### 3.id命令

- 作用：查看一个用户的基本信息，包含用户id、用户组id、附加组id.....、该指令如果不指定用户，则默认查看当前用户的信息

```
id
id root
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-19-19-04-image.png)

## <2>创建用户和组

### 1.创建用户

- 命令：useradd

- 作用：添加用户

- 语法
  
  ```
  useradd 选项 用户名 
  ```
  
  ```
  useradd test5
  ```

### 2.创建组

- 命令：groupadd

- 作用：添加一个组

- 语法：
  
  ```
  groupadd 选项 组名
  ```

- 选项
  
  - -g 设置用户组的gid，如果不指定，则默认从1000之后递增

```
groupadd -g 1600 TestGroup
```

## <3>修改用户和组

#### 1. passwd命令

- 作用 ： 修改用户的密码

- 语法
  
  ```
  passwd 用户名
  ```
  
  > 不指定用户名的话，默认修改当前用户的密码

- **/etc/shadow文件**

​ 由于 /etc/passwd文件允许所有用户读取，易导致用户密码泄露，因此 Linux 系统将用户的密码信息从 /etc/passwd 文件中分离出来，并单独放到了shadow文件中。

​ /etc/shadow 文件只有 root 用户拥有读权限，其他用户没有任何权限，这样就保证了用户密码的安全性。

用户设置密码之后，会自动在/etc/shadow文件中进行体现**/etc/shadow文件**

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-19-36-54-image.png)

第一列为用户名，后面是加密后的密码，就是$开头的字符串

如果显示为!!,则表示这个用户没有设置密码。

同 `/etc/passwd` 文件⼀样，文件中每行代表⼀个用户，同样使用 `:` 作为分隔符，不同之处在于，每行用户信
息被划分为 9 个字段。每个字段的含义如下：

- 用户名
- 加密密码
- 最后⼀次修改时间
- 最小修改时间间隔
- 密码有效期
- 密码需要变更前的警告天数
- 密码过期后的宽限时间
- 账号失效时间
- 保留字段

### 2. usermod

作用：修改用户的信息

用法：

```
usermod 选项 用户名
```

选项：

- -d 修改账户家目录
- -e 修改账户失效日期
- -g 修改账户所属基本组
- -G 修改账户所属附加组
- -s 修改账户登录Shell
- -u 修改账户 UID
- **-L：锁定用户，锁定后用户无法登陆系统lock**
- **-U：解锁用户unlock**

> 修改用户时，可以直接设置是否锁定该用户

##### (1)锁定用户账户的影响：

1. **禁止用户登录**：用户无法使用密码通过常规的身份验证方法登录系统。
2. **不影响文件访问**：用户锁定后仍然能够访问他们的文件，只是不能登录系统。
3. **SSH 等服务仍然受影响**：通过 SSH 或其他服务登录时，也会被拒绝。

### 3. groupmod

作用：修改用户组的信息

语法：

```
groupmod 选项 组名
```

选项：

- -g ：gid缩写，设置一个自定义的用户组ID 数字

- -n ：name缩写，设置新的用户组的名称

```
groupmod -g 1700 -n Group3 TestGroup
```

## <4>删除用户和组

#### 1.userdel

- 作用：删除用户

- 语法
  
  ```
  userdel 选项 用户名
  ```

- 选项
  
  - -r 删除用户的同时，删除其对应的家目录

例子：

- 不加-r选项删除用户
  
  ```
  userdel test
  ```

加 -r 选项

```
userdel -r test1
```

### 2.groupdel

作用：删除用户组

语法：

```
groupdel 组名
```

```
groupdel Group3
```

## <5>su和sudo

### 1.su 命令

作用：切换用户

语法：

```
su [-] 用户
```

- 切换用户时，**要输入目标用户的密码**

- 切换到root用户时，可以使用`su -`

```
su -
```

- 切换用户之后前后的工作路径是不变的，**添加了选项[-]会自动切换到用户的家**；
  
  <img title="" src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-20-19-43-18-image.png" alt="" width="600">

### 2.sudo

作用：允许授权用户以超级用户的权限执行命令，而无需切换到root用户。

- 使用sudo权限时，**<u>要输入当前用户的密码</u>**
  
  <img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-20-19-44-06-image.png" title="" alt="" width="602">

# 四、Linux权限管理

## <1>Linux权限概述

​ 在多用户计算机系统的管理中，权限是指某个特定的用户具有特定的系统资源使用权利。

在Linux 中分别有读、写、执行权限：

| 类型  | 权限针对文件                                             | 权限针对目录                                 |
| --- | -------------------------------------------------- | -------------------------------------- |
| 读r  | read，表示可以查看文件内容；cat                                | 表示可以(ls)查看目录中存在的文件名称                   |
| 写w  | write，表示可以更改文件的内容；vim 修改，保存退出                      | 表示是否可以删除目录中的子文件或者新建子目录(rm/touch/mkdir) |
| 执行x | execute，表示是否可以开启文件当中记录的程序,一般可以执行的脚本文件(.sh)，或者二进制程序 | 表示是否可以进入目录中(cd)                        |

## <2>Linux文件所有者

> ugo权限

对于文件的所有者，又分为3类：

- **user(属主）**
  
  **文件的创建者或拥有者**，换句话说，**某个账户**对文件有的权限。

- **group（属组）**
  
  文件所属的用户组，换句话或，某个**用户组**对这个文件有的权限。

- **other（其他用户）**
  
  **除了上面提到的属主和属组之外的所有用户**，对这个文件有的权限

## <3>普通权限管理

### 1.查看文件权限

命令： ls -l

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-09-03-26-image.png" title="" alt="" width="625">

### 2.文件权限详解

Linux 中存在三类身份：

- 属主(u拥有者)

- 属组(g用户组)

- 其他用户（o）
  
  ls -l的结果详解：
  
  <img title="" src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-09-04-20-image.png" alt="" width="633">

### 3.chmod设置文件/目录的权限

命令：chmod

语法：

```
chmod [选项] 权限模式 目标文件
```

作用：添加或者删除目标文件/目录的ugo权限

选项：

- -R 递归将权限应用到所有的子目录和子文件

**注意：如果要给文件设置权限，操作者要么是root用户，要么是文件的所有者**

#### 3.1 用字母形式设置

> 用前面提到的u、g、o的方法设置

> 不加u、g、o的话，默认对所有权限组进行设置，只能设置单个权限

- 用法一：chmod 要增加权限的所有者+要增加的权限 文件名

```bash
chmod  u+x 1.txt
含义：1.txt文件，给属主增加执行权限
```

> 使用chmod u+x 之后，1.txt文件权限的属主一栏，加上了x权限，也就是可执行权限

- 用法二：chmod 多个要增加的权限 文件名

> 相当于可以同时对不同的权限分类设置权限，下面的例子就是对**属组和其他**同时设置权限

```bash
示例代码：
chmod  g+x,o+x 1.txt
注意：同时改变多个对象的权限，中间使用“逗号“分割。
```

- 用法三：chmod 要减少的权限 文件名

```
chmod u-r 1.txt
减少对应权限组的权限
```

- 用法四：chmod 要赋予的权限 文件名---------批量给权限
  
  ```
  示例代码：
  chmod u=rwx,g=rwx,o=rwx 1.txt
  含义：对于1.txt文件，给属主，属组，其他，都 赋予 读，写，执行权限
  ```
  
  > 要达到上述效果，也可以使用 chmod a+rwx 1.txt

- 用法五：chmod -R 要赋予的权限 目录

- ls -ld 123 -d选项，只查看目录本身的权限，不查看目录中的内容
  
  <img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-09-07-58-image.png" title="" alt="" width="574">
  
  **chmod -R a=rwx 123**
  
  <img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-09-08-58-image.png" title="" alt="" width="574">

#### 3.2 用数字形式设置

> 想要给什么权限，就把对应权限的数字加起来

经常会在技术网站上看到类似于chmod 777 a.txt 这样的命令，这种形式称之为**数字形式权限**。

**文件权限对应关系(重点)**

| 权限  | 对应数字 | 意义   |
| --- | ---- | ---- |
| r   | 4    | 可读   |
| w   | 2    | 可写   |
| x   | 1    | 可执行  |
| -   |      | 无此权限 |

**权限与数字对应详解**

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-09-11-41-image.png" title="" alt="" width="606">

```powershell
用法六：chmod 要赋予的权限（数字形式） 文件名
示例代码：
chmod 765 quanxian.txt
含义：对于quanxian.txt文件，给属主所有权限，属组读写权限，其他读和执行权限
注意：
全部权限：7 = r+w+x = 4 + 2 + 1
读写权限：6 = r+w = 4 + 2
读和执行：5 = r+x = 4 + 1
综上所述，u=7，g=6，o=5
```

## <4>文件的属主与属组

**基本语法：`ls -l`查看文档属主与属组**

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-09-15-57-image.png" title="" alt="" width="618">

### 1.chown修改文件的属主

基本语法：

```
chown [-R] 文件新的所有者 目录
```

作用：更改文件/目录的所有者 （change owner）

选项：-R 递归修改所有者

例子：

- 修改1.txt的所有者为test2

```
chown test2 1.txt
```

- 递归修改123目录下的所有文件和子目录的所有者

```
chown -R test2 1.txt
```

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-09-17-38-image.png" title="" alt="" width="646">

### 2.chgrp修改文件的属组

基本语法：

```
chgrp [-R] 文件新的所有者 目录
```

作用：更改文件的所属组（change group）

选项：-R 递归修改所有者

例子：

- 修改1.txt的所属组为test2

```
chgrp test2 1.txt
```

- 递归修改123目录下的所有文件和子目录的所属组

```
chgrp -R test2 123
```

### 3.chown同时修改属主与属组(重点)

用法：

```
chown [-R] 属主名:属组名 目标
```

例子：

- 修改 1.txt 文件的属主和属组都为root

```
chown root:root 1.txt
```

- 递归修改目录中的属主和属组

```
chown -R root:root 123
```

## <5>ACL访问控制

**getfacl命令：查看文件的ACL策略及权限**

**setfacl命令： 给文件针对某个用户或者某个组来增加（设置）ACL策略**

### 1.getfacl命令

```
getfacl 目标
```

 ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-09-24-04-image.png)

### 2.setfacl

作用：修改或删除acl权限

- -m ： 修改acl策略

- -x ：去掉某个用户或者某个组的权限

- -b ：删除所有的acl策略

- -R ：递归,通常用在文件夹

mask：mask定义除other和所有人(拥有者)外的最大权限

```powershell
setfacl -m u:用户名:rwx /usr/local/shichangbu  给单个用户单独加权限
setfacl -m g:用户组名:rwx /usr/local/shichangbu   给单个组单独加权限

setfacl -x u:用户 /usr/local/shichangbu  去掉某个用户的权限
setfacl -x g:组名 /usr/local/shichangbu    去掉某个组的acl策略

setfacl -b -R /usr/local/shichangbu  删除所有的acl策略,递归子文件

例如：
setfacl -m u:user01:rw   file1 针对于单个用户给可读可写权限
setfacl -m g:sysadmin:rw file1 针对于单个组给可读可写权限
```

setfacl命令解释

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-09-26-03-image.png" title="" alt="" width="667">

例子：

- 为test2用户在1.txt上设置只读权限
  
  ```
  setfacl -m u:test2:r 1.txt
  ```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-09-26-59-image.png)

# 五、Linux服务管理

## <1>查看服务(systemctl)

命令：systemctl

作用：管理服务

语法：

```
systemctl 选项
```

选项：

- systemctl list-units --type service --all：列出所有服务（包含启动的服务和没启动的）
- systemctl list-units --type service --state running：列出已经启动的服务

## <2>查看服务的状态

命令：systemctl

作用：管理服务

语法：

```
systemctl 选项 目标服务
```

选项:

- status：检查服务的状态

```
systemctl status sshd
```

## <3>启动和停止服务

命令：systemctl

作用：管理服务

语法：

```
systemctl 选项 目标服务
```

选项:

- start：启动服务
- stop：停止服务
- restart：重启服务
- reload：重新加载指定服务的配置文件（不是所有的服务都支持重载）

## <4>服务持久化(开机自启动)

持久化就是服务是否开机自动启动

命令：systemctl

作用：管理服务

语法：

```
systemctl 选项 目标服务
```

选项:

- enable：指定服务开机自动启动

- disable：禁止服务开机自动启动
  
  **systemctl参数总结**
  
  | 参数                              | 含义                                         |
  | ------------------------------- | ------------------------------------------ |
  | list-units --type service --all | 列出所有服务                                     |
  | list-units --type service       | 列出所有启动的服务                                  |
  | start                           | 启动指定服务                                     |
  | stop                            | 停止指定服务                                     |
  | status                          | 检查指定服务的运行状况                                |
  | restart                         | 重启指定服务                                     |
  | reload                          | 重新加载指定服务的配置文件（并非所有服务都支持reload，通常使用restart) |
  | enable                          | 开启 服务开机自动启动                                |
  | disable                         | 取消 服务开机自动启动                                |

## <5>常用自有服务（ntp,firewalld,crond)

| 服务名       | 含义              |
| --------- | --------------- |
| ntpd      | 用于同步计算机的系统时间的服务 |
| firewalld | 防火墙服务           |
| crond     | 计划任务服务          |

## <6>firewalld防火墙的配置

### 1.查看，开启和停止firewalld服务

命令：systemctl

作用：管理服务

语法：systemctl [选项] firewalld

选项：

- status：检查指定服务的运行状况

- start：启动指定服务

- stop：停止指定服务

- restart：重启指定服务

- reload：重新加载指定服务的配置文件（并非所有服务都支持reload，通常使用restart)

### 2.管理firewall配置

命令：firewall-cmd

作用：管理firewall具体配置

语法：firewall-cmd [参数选项1] ....[参数选项n]

##### ①查看默认使用的区域

```
firewall-cmd --get-default-zone 
```

##### ②列出当前使用区域配置

```
firewall-cmd --list-all
```

##### ③查看所有可用的区域

```
firewall-cmd --get-zones
```

##### ④列出所有区域的配置

```
firewall-cmd --list-all-zones
```

##### ⑤添加允许通过的服务或端口

> 如果想测试，可以使用python3 -m http.server 80 建立一个简易http服务器，测试防火墙规则，安装python3使用 yum -y install python3

```powershell
示例代码：
firewall-cmd --zone=public --add-port=80/tcp
含义:在public区域，添加允许tcp协议的80端口通过的规则

firewall-cmd --zone=public --add-service=http
含义:在public区域，添加允许http服务通过的规则
```

> 不指定--zone的话，会在默认区域添加规则

##### ⑥去掉允许通过的服务或端口

```powershell
示例代码：
firewall-cmd --zone=public --remove-port=80/tcp
含义:在public区域，去掉允许tcp协议的80端口通过的规则

firewall-cmd --zone=public --remove-service=http 
```

##### ⑦ 封锁与解封指定的IP

封锁 IP: 192.168.127.152

```shell
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.127.152" reject' 
```

命令参数解释:

- --zone=public:指定操作的zone为public
- --add-rich-rule: 添加自定义规则
- rule family="ipv4":指定ipv4规则
- source address="192.168.127.152":匹配源IP192.168.127.152
- reject: 注明采用拒绝策略

解封 IP: 192.168.127.152

```shell
firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="192.168.127.152" reject'
```

##### ⑧永久模式参数permaent

```powershell
用法七：firewall-cmd --permanent --zone=public --add-port=1024/tcp
含义:在public区域，使用permanent参数，永久添加允许1024端口通过的规则
```

> 相当于把规则写入了配置文件

##### ⑨重新加载配置reload

```powershell
用法七：firewall-cmd --reload
含义:重新加载配置
```

## <7>计划任务crontab

### 1.查看计划任务

语法：

```
crontab 选项
```

常用选项：

- -l：list，列出指定用户的计划任务列表
- -e：edit，编辑指定用户的计划任务列表，简单来说，计划任务就是一个文件==
- -u：user，指定的用户名，如果不指定，则表示当前用户
- -r：remove，删除指定用户的计划任务列表

例子：

- 列出当前用户的计划任务列表

```
crontab -l 
```

**拓展：**

`crontab -e` 和 `vim /etc/crontab` 是两种添加或编辑计划任务的方法:

crontab -e:

- 这个命令会打开当前用户的 crontab 文件进行编辑,文件位置是 /var/spool/cron/用户名
- 添加的任务只对当前用户生效
- 一般用户可以使用这个命令添加自己的定时任务

vim /etc/crontab:

- 这个命令会直接编辑系统级的全局 crontab 文件 /etc/crontab
- 在这个文件中添加的任务是对所有用户都生效
- 只有 root 用户才有权限直接编辑这个文件

两者的主要区别在于:

- crontab -e 添加用户个人任务
- vim /etc/crontab 添加系统范围内对所有用户生效的任务

在使用上:

- 普通用户添加个人任务使用 crontab -e
- 作为管理员添加系统范围任务需要用 root 用户通过 vim /etc/crontab

所以总的来说:

- crontab -e 用来管理个人任务
- vim /etc/crontab 用来管理系统全局任务

### 2.编辑计划任务（重点）

进入计划任务编辑文件

打开计划任务编辑文件后，可以在此文件中编写我们自定义的计划任务：

- 计划任务的规则语法格式，以行为单位，一行则为一个计划：

```
分 时 日 月 周  需要执行的命令
```

- 五个星号默认是每分钟执行

```
* * * * * 命令
```

例如：

- 每天0时0分执行reboot指令。

```
1,2,6 * * * * reboot
```

```powershell
取值范围（常识）：
分：0~59
时：0~23
日：1~31
月：1~12
周：1~7

四个符号：
*：表示取值范围中的每一个数字
-：做连续区间表达式的，要想表示1~7，则可以写成：1-7
/：表示每多少个，例如：想每 10 分钟一次，则可以在分的位置写：*/10
,：表示多个取值，比如想在 1 点，2 点 6 点执行，则可以在时的位置写：1,2,6
```

> 特别补充：在Linux系统中，有些命令不能直接在计划任务中使用，使用后，其也不会生效。如useradd命令。如果想让其生效必须使用完整路径

问题：如何查询一个命令的真实路径在哪个位置？

> 答：使用whereis 命令名称

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-09-45-57-image.png)

> 分 时 日 月 周 需要执行的命令

问题1：每月1、10、22 日的4:45 重启network 服务

```
45 4 1,10,22 * * systemctl restart network
```

问题2：每周六、周日的1:10 重启network 服务

```
10 1 * * 6,7 systemctl restart network
```

问题3：每天18:00 至23:00 之间每隔30 分钟重启network 服务

```
*/30 18-23 * * * systemctl restart network
```

问题4：每隔两天的上午8 点到11 点的第3 和第15 分钟执行一次重启

```
3,15 8-11 */2 * * reboot
```

案例：每1 分钟往 root 家目录中的 readme.txt 中输一个1，为了看到效果使用追加输出【输出使用echo 命令，语法：# echo 输出的内容】

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-09-46-53-image.png)

在末行模式下输入`:wq`保存并退出，使用tail -f查看readme.txt动态变化

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-09-47-38-image.png" title="" alt="" width="888">

## <8>扩展

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-09-53-28-image.png)

## <9>关于rpm的一些操作

### 1.查询某个软件安装情况

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-16-23-31-image.png)

### 2.卸载某个软件

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-16-27-30-image.png)

### 3.安装某个软件

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-16-30-22-image.png)

### 4.更新某个软件

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-16-16-33-29-image.png" title="" alt="" width="858">

### 5.查看文件所属包名

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-16-34-25-image.png)

# 六、Linux进程检测与控制

## <1>top查看 CPU使用情况

命令：top

作用：查看服务器进程占用的资源（100%使用）

语法：top （动态显示）

交互操作快捷键：

- M（大写）：表示将结果按照内存（MEM）从高到低进行降序排列；
- P（大写）：，表示将结果按照CPU 使用率从高到低进行降序排列；
- 1 ：当服务器拥有多个cpu 的时候可以使用“1”快捷键来切换是否展示显示各个cpu 的详细信息；
- q：退出

#### 扩展：如何获取CPU的总核心数？

grep 'core id' /proc/cpuinfo |sort -u |wc -l

## <2>free查看内存情况

命令：free

作用：查看内存使用情况

语法：free -m

选项：

- -m 以mb为单位查看
- ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-19-09-58-image.png)

## <3>df查看磁盘

命令：df

作用：查看磁盘的空间(disk free)

语法：df [-h]

选项：

- -h 使用人类可读的形式展示大小
  
  ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-19-11-26-image.png)

| Filesystem | 磁盘名称                  |
| ---------- | --------------------- |
| Size       | 总大小                   |
| Used       | 被使用的大小                |
| Avail      | 剩余大小                  |
| Use%       | 使用百分比                 |
| Mounted on | 挂载路径（相当于Windows 的磁盘符） |

## <4>ps命令查看进程

命令：ps（process show进程显示）

语法：ps [参数选项]

作用：主要是查看服务器的进程信息

选项：

- -e：等价于“-A”，表示列出全部（all）的进程

- -f : 表示full，显示全部的列（显示全字段）

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-19-18-40-image.png)

| UID   | 该进程执行的用户ID                                        |
| ----- | ------------------------------------------------- |
| PID   | 进程ID                                              |
| PPID  | 该进程的父级进程ID，如果找不到，则该进程就被称之为僵尸进程（Parent Process ID） |
| C     | Cpu的占用率，其形式是百分数                                   |
| STIME | 进程的启动时间                                           |
| TTY   | 终端设备，发起该进程的设备识别符号，如果显示“?”则表示该进程并不是由终端设备发起         |
| TIME  | 进程实际使用CPU的时间                                      |
| CMD   | 该进程的名称或者对应的路径                                     |

### 1.ps命令配合grep命令筛选某个用户的进程（此处是root用户）

```
ps -ef | grep root
```

### 2.ps命令配合grep命令筛选某个程序的进程（此处是筛选ssh相关进程）

```
ps -ef | grep ssh
```

## <5><mark> netstat查看网络进程情况</mark>

命令：netstat

作用：查看网络连接状态

语法：

```
netstat -anpt
```

选项：

- -t：表示只列出tcp 协议的连接；
- -n：表示将地址从字母组合转化成ip 地址，将协议转化成端口号来显示；
- -a : 显示"state（状态）"列中的所有连接。
- -p：表示显示发起连接的进程pid 和进程名称；
- -l ：表示过滤出"state（状态）"列中其值为LISTEN（监听）的连接；

例子：

- 查看当前主机的网络连接情况

```
netstat -anpt
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-19-38-38-image.png)

Protocol：协议（tcp、upd、http、https、icmp、ssh…）
Receive：接收
Send：发送
Local Address:本地地址
Foreign：远程地址
State：状态，LISTEN表示侦听来自远方的TCP端口的连接请求
PID/Program name：进程ID和程序名

## <6>网络相关的一些命令

### 1.ping命令

作用：检查网络的连通性

用法：

```
ping ip/域名
```

选项：

- -c 指定发送的报文数

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-19-52-11-image.png)

### 2.ifconfig命令

作用：查看/设置网卡信息

用法：

- 查看
  
  ```
  ifconfig [网卡名]
  ```

- 临时配置网卡ip
  
  ```
  ifconfig 网卡名 ip/子网
  ```

- 禁用和激活网卡
  
  ```
  ifconfig 网卡名 up/down
  ```

- centos7网卡的配置文件路径：
  
  ```
  /etc/sysconfig/network-scripts/ifcfg-ens33
  ```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-16-19-53-02-image.png)

### 3.nslookup

作用：测试dns解析

用法：

```
nslookup 域名
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-10-41-55-image.png)

### 4.curl

作用：发起http请求

用法：

```
curl 链接
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-10-43-39-image.png)

### 5.wget

作用：非交互式的网络文件下载工具

用法：

```
wget 链接
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-10-44-45-image.png)

### 6.kill

命令：kill

语法：kill [信号] PID

作用：kill 命令会向操作系统内核发送一个信号（多是终止信号）和目标进程的 PID，然后系统内核根据收到的信号类型，对指定进程进行相应的操作

| 信号编号 | 含义                     |
| ---- | ---------------------- |
| 9    | 杀死进程，即强制结束进程。          |
| 15   | 正常结束进程，是 kill 命令的默认信号。 |

例子：

查询crond程序的PID，并强制结束它

  查询PID

```
ps -ef | grep crond
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-13-55-23-image.png)

强制结束crond的进程

```
kill -9 11405
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-13-56-13-image.png)

查看crond服务的状态

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-13-56-52-image.png)

### 7.killall关闭进程

命令：killall

作用：通过程序的进程名来**杀死一类进程**

语法：killall [信号] 进程名称

信号种类：和kill相同，这里不再重复

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-20-14-09-51-image.png)

# 七、LAMP项目部署

## <1>关于YUM

在CentOS系统中，软件管理方式通常有三种方式：

- yum安装
- rpm安装
- 编译安装

安装方式的难度：编译安装 > rpm安装 > yum安装（有网络 + yum源支持）

Yum（全称为 `Yellow dog Updater, Modified`）是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。

基于rpm包管理，能够从**指定的服务器**(yum源）自动下载RPM包并且安装，可以**自动处理依赖关系**，**并且一次安装所有依赖的软件包**，无须繁琐地一次次下载、安装。

  rpm和yum区别？答：① yum底层也是基于rpm进行安装的（yum安装的软件，可以通过rpm -qa进行查询） ② yum相对于rpm最大的优势，可以解决依赖关系。

**yum命令详解**

- **搜索要安装的软件**

```powershell
yum search 软件名称的关键词
```

案例：搜索仓库中的vim软件

```powershell
yum search vim
```

案例：搜索firefox火狐浏览器

```powershell
yum search firefox
```

- **使用yum安装软件**

基本语法：

```powershell
yum install 软件名称关键词 [选项]
选项：
-y ：yes缩写，确认安装，不提示。
```

案例：使用yum命令安装vim编辑器

```powershell
yum install vim -y
```

案例：使用yum命令安装firefox浏览器

```powershell
yum install firefox -y
```

- **使用yum卸载软件**

```powershell
yum remove 软件名称关键词 [选项]
选项：
-y ：yes缩写，确认卸载，不提示。
```

案例：把firefox火狐浏览器进行卸载操作

```powershell
yum remove firefox -y
```

- **使用yum更新软件**

基本语法：

```powershell
yum update 软件名称关键词 [选项]
选项：
-y ：yes缩写，确认更新，不提示
```

案例：把vim编辑器进行更新操作

```powershell
yum update vim -y
```

## <2>LAMP

### 1.LAMP概述

**LAMP：Linux + Apache + MySQL + PHP LAMP 架构（组合）**

**LNMP：Linux + Nginx + MySQL + php-fpm LNMP 架构（组合**）

**LNMPA：Linux + Nginx(80) + MySQL + PHP + Apache Nginx 代理方式**

  Apache：Apache是世界使用排名第一的**Web服务器软件**。

  PHP：一种专门用于Web开发的编程语言。

  MySQL：MySQL是一个关系型数据库管理系统，主要用于永久存储项目数据。

### 2.LAMP三者之间的关系

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-10-10-34-image.png)

Apache：用于接收用户的请求（输入网址，返回网页=>结果）

PHP：注册、登录、加入购物车、下单、支付等动态功能（有编程语言的支持）

MySQL：**永久保存数据**，比如你在网站上注册的用户和密码、你加入购物车的产品、你的产品订单

LAMP = Linux + APache + PHP + MySQL

# 八、SSH服务

## <1>SSH的概念

`SSH` 为 Secure Shell 的缩写，是建立在应用层基础上的安全协议。**<u>SSH是较为可靠的专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。</u>**

OpenSSH 服务是 SSH 协议的免费开源实现，可以用来进行远程控制， 或在计算机之间传送文件。**而实现此功能的传统方式**，如telnet(终端仿真协议)、 rdp（远程桌面协议）、ftp（文件传输协议）、 rlogin、rsh都是极为不安全的，**并且会使用明文传送密码**。OpenSSH提供了服务端后台程序和客户端工具，用来加密远程控制和文件传输过程中的数据，并由此来代替原来的类似服务。

通过使用SSH，你可以把所有传输的数据进行加密，这样可以较好地抑制"中间人"这种攻击，也可能够防御DNS欺骗和IP欺骗。

## <2>SSH的简单使用

### 1.登录ssh

```
ssh 用户名@IP地址，不加用户名则以当前终端用户身份远程连接，如果两端用户名不一样，则需要使用-l username指定用户名
exit  退出远程连接
```

例子：

- kali连接centos
  
  ```
  ssh root@192.168.26.129
  ```

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-15-03-43-image.png" title="" alt="" width="712">

### 2.scp命令

- 将本机文件复制到远程服务器(centos)上（上传）
  
  ```
  scp ./123.txt root@192.168.26.129:/root/test 
  ```

**<mark>其中./表示当前目录</mark>**

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-15-25-05-image.png)

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-15-26-15-image.png)

  将远程服务器上的文件复制到本机（下载）

```
scp root@192.168.26.129:/root/test/down.txt ./
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-15-35-55-image.png)

注意两点：

1.如果远程服务器openssh有特殊限制，scp便要走特殊端口，具体用什么端口视情况而定，命令格式如下：

```
scp -P 2222 [username]@[主机地址]:/usr/local/sin.sh /home/administrator
```

2.使用scp要注意所使用的**用户是否具有可读取远程服务器相应文件的权限**。

### 3.可使用systemctl命令查看和设置openssh服务的状态。

```
systemctl status sshd    #查看ssh状态
systemctl start sshd     #启动ssh服务
systemctl stop sshd     #停止ssh服务
```

## <3>公私钥认证

`ssh`服务主要有两种登录方式：第一种为密码口令登录，第二种为公钥登录。

下面我们来解释一下公私钥的概念：

密码体系从加密和解密方面来分类的话，可以分为**对称加密**和**非对称加密**。

- 对称加密：加密和解密使用的密钥是同一个。
- 非对称加密：加密和解密使用的密钥是不同的，采用两个密钥。
- 对称加密解密的速度比较快，非对称加密和解密花费的时间长、速度相对较慢。
- 对称加密的安全性相对较低，非对称加密的安全性较高。

公私钥体系是常见的非对称加密，每个通信方均需要两个密钥，即公钥和私钥，这两把密钥可以互为加解密。公钥是公开的，不需要保密，而私钥是由个人自己持有，并且必须妥善保管和注意保密。其特性为：

- 一个公钥对应一个私钥。
- 密钥对中，让大家都知道的是公钥；不告诉大家，只有自己知道的，是私钥。
- 如果用其中一个密钥加密数据，则只有对应的那个密钥才可以解密。
- 如果用其中一个密钥可以进行解密数据，则该数据必然是对应的那个密钥进行的加密。

ssh服务通过密码进行登录，主要流程为：

1. 客户端连接上服务器之后，服务器把自己的公钥传给客户端
2. 客户端输入服务器密码通过公钥加密之后传给服务器
3. 服务器根据自己的私钥解密登录密码，如果正确那么就让客户端登录

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-15-57-30-image.png" title="" alt="" width="614">

ssh服务公钥登录，主要流程为：

1. 客户端生成RSA公钥和私钥
2. 客户端将自己的公钥存放到服务器
3. 客户端请求连接服务器，服务器将一个随机字符串发送给客户端
4. 客户端根据自己的私钥加密这个随机字符串之后再发送给服务器
5. 服务器接受到加密后的字符串之后用公钥解密，如果正确就让客户端登录，否则拒绝。这样就不用使用密码了。

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-15-58-20-image.png" title="" alt="" width="619">

### 公私钥登录方法

- 首先生成一对密钥

```
ssh-keygen -t rsa
```

<img title="" src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-16-01-02-image.png" alt="" width="600">

  把id_rsa.pub公钥文件放到想要登录的用户的 ~/.ssh/目录中，并改名为authorized_keys

```
mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
```

<img title="" src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-16-10-29-image.png" alt="" width="924">

把私钥文件放到想要远程登录的机器上

> 可以使用scp

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-16-12-20-image.png)

使用私钥登录

> 不用密码就可以登录了

```
ssh -i id_rsa root@192.168.26.129
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-16-20-26-image.png)

## <4>openssh配置文件与加固

- `ssh_config`为客户端配置文件。

- `sshd_config`为服务端配置文件。

我们实验修改的皆为**sshd_config**，即服务端配置文件，为的是规定主机**被远程登录时**的状态。

### 实验1：修改 SSH 默认端口

```
vim /etc/ssh/sshd_config
```

- 在配置文件中 Port 2222 这一行

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-16-59-14-image.png" title="" alt="" width="438">

- 重启sshd服务

```
systemctl restart sshd
```

- 查看当前ssh服务的监听端口

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-17-03-54-image.png)

使用ssh命令行工具连接

```
ssh -p  2222 root@192.168.127.155
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-17-08-21-image.png)

### 实验2：配置ssh日志

在此实验中，将学习在ssh配置文件中配置ssh日志。

```
vim /etc/ssh/sshd_config    
```

`SyslogFacility AUTHPRIV` 表示当有人使用ssh登录系统时，ssh会记录信息，记录类型为AUTHPRIV。 `#LogLevel INFO`表示设置记录sshd日志信息的级别。

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-17-34-03-image.png)

`SyslogFacility`一项，规定了服务日志的性质，也规定了服务日志存储的默认路径。

如：`AUTHPRIV` 表达了日志记录的是包含敏感信息的用户身份验证消息，默认存储于`/var/log/secure`。

`AUTH` 则表达了日志记录的是不包含敏感信息的用户身份验证消息，同样默认存储于`/var/log/secure`。

ssh配置文件的这一字段一般是不需要修改的。在LInux系统的其他服务配置文件中，你可能会遇见`SyslogFacility`设置为其他状态的情况，可以通过下表了解其含义。

| 设置           | 描述                                 | 默认日志文件                          |
| ------------ | ---------------------------------- | ------------------------------- |
| **local0**   | BIG-IP 特定消息                        | **/var/log/ltm**                |
| **local1**   | EM 特定消息 APM 特定消息                   | **/var/log/em /var/log/apm**    |
| **loacl2**   | GTM 和链路控制器特定消息                     | **/var/log/gtm**                |
| **local3**   | ASM 特定消息                           | **/var/log/asm**                |
| **loacl4**   | ITCM 门户和服务器 (iControl) 特定消息        | **/var/log/ltm**                |
| **loacl5**   | 包过滤特定消息                            | **/var/log/pktfilter**          |
| **loacl6**   | HTTPD 特定消息                         | **/var/log/httpd/httpd_errors** |
| **loacl7**   | Linux 特定的引导消息                      | **/var/log/boot.log**           |
| **cron**     | 与**cron**进程相关的消息                   | **/var/log/cron**               |
| **daemon**   | 与系统守护进程相关的消息（包括**named**和**ntpd**） | **/var/log/daemon.log**         |
| **kern**     | 内核消息                               | **/var/log/kern.log**           |
| **mail**     | 邮件系统消息                             | **/var/log/maillog**            |
| **auth**     | 不包含敏感信息的用户身份验证消息                   | **/var/log/secure**             |
| **authpriv** | 包含敏感信息的用户身份验证消息                    | **/var/log/secure**             |
| **user**     | 与用户进程相关的消息                         | **/var/log/user.log**           |

`#LogLevel INFO`表示设置记录sshd日志信息的级别。可以理解为设置了日志的详细程度。

`INFO`级别代表了日志会报告大部分有用信息，是较为详细的日志等级，除此外，还有其他等级：

| 等级          | 描述               | 冗长度  |
| ----------- | ---------------- | ---- |
| **emerg**   | 紧急系统紧急信息         | 最低限度 |
| **alert**   | 需要管理员干预的严重错误     | 低的   |
| **crit**    | 严重错误，包括硬件和文件系统故障 | 低的   |
| **err**     | 非关键但可能非常重要的错误消息  | 低的   |
| **warning** | 至少应该记录以供审查的警告消息  | 中等的  |
| **notice**  | 包含有用但可能会被忽略的消息   | 中等的  |
| **info**    | 包含有用但可能会被忽略的消息   | 高的   |
| **debug**   | 含有最详细的信息         | 最大值  |

将此条注释取消，将其修改为`LogLevel DEBUG`，重启ssh服务，观察修改前后日志详细度的变化。

```
tail -f /var/log/secure        查看日志
LogLevel DEBUG
systemctl restart sshd.service    重启服务
ssh 192.168.229.135  使用kali进行ssh连接
tail -f /var/log/secure        查看日志
```

日志默认详细级别：

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-17-34-38-image.png" title="" alt="" width="919">

DEBUG级别：（一次登录日志一屏装不下）

<img title="" src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-17-35-12-image.png" alt="" width="914">

实验结束后将其改回`INFO`级别并重启sshd服务，避免影响后续实验。

### 实验3：禁止root用户登录

```
vim /etc/ssh/sshd_config
```

- / 搜索 PermitRootLogin

- 取消注释，并设置PermitRootLogin 为 no

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-17-42-59-image.png)

- 重启sshd服务
  
  ```
  systemctl restart sshd
  ```

- 最终效果，root用户无法登录

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-17-44-50-image.png" title="" alt="" width="600">

### 实验4：配置长时间无操作自动断开ssh链接

#### 1.认证阶段长时间无操作断开连接

- 指定时间内没有成功登录（密码认证阶段），会断开连接

在配置文件37行的`#LoginGraceTime 2m`

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-18-12-22-image.png)

#### 2.登录后长时间无操作断开连接

- 修改**登录成功后**长时间无操作断开：在配置文件`/etc/profile`末尾加上

```bash
vi /etc/profile
export TMOUT=10      单位是秒，时间太短来不及敲命令
```

- 执行该命令，使配置文件生效

```
source /etc/profile        重新加载系统环境变量文件 /etc/profil
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-18-13-07-image.png)

可以看到，当命令终端超过10秒无人操作，ssh连接自动断开了。

**实验结束后将其改回，避免影响后续实验。**

### 实验5：开启空口令登录

**慎用！禁用！**

配置文件`/etc/ssh/sshd_config`64行的`PermitEmptyPasswords no`，默认设置禁止空口令登录，将其取消掉`#`注释并将`no`改为`yes`，更改完后记得**重启**sshd服务使配置文件生效

```
vi /etc/ssh/sshd_config
systemctl restart sshd
```

注：使用空口令登录须开启密码认证

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-18-18-56-image.png)

清除zhangsan用户密码

```
passwd -d zhangsan
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-18-19-23-image.png)

测试空口令登录成功

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-18-20-18-image.png)

实验结束后将其改回，避免影响后续实验。

### 实验6：访问速度调优

```
vi /etc/ssh/sshd_config
```

将此两行改为no可解决ssh链接慢的问题

```bash
GSSAPIAuthentication no      #关闭GSSAPI认证
UseDNS no                    #关闭DNS解析
```

```
systemctl restart sshd.service    重启sshd服务使配置文件生效
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-18-25-59-image.png)

一般 SSH 依次进行的认证方法的是 publickey, gssapi-keyex, gssapi-with-mic, password。 一般用户只使用 password 认证方式，但前面 3 个认证过程系统还是会尝试，这就浪费时间了，也就造成 SSH 登录慢。GSSAPI 主要是基于 Kerberos 的，因此要解决这个问题也就变成要系统配置有 Kerberos， 一般用户是没有配置 Kerberos的。

### 实验7：启用密码策略

> ```
> minlen = 8
> minclass = 4
> maxrepeat = 2
> maxclassrepeat = 2
> lcredi = 1
> ucredit = 1
> dcredit = 1
> ocredit = 1
> ```

启用密码策略有两个配置文件： 第一个是`/etc/login.defs` ，修改文件里的策略

```bash
vi /etc/login.defs
PASS_MAX_DAYS 99      #密码99天过期
PASS_MIN_DAYS  1      #修改密码最小间隔为1天
PASS_MIN_LEN   8      #密码最短长度为8
PASS_WARN_AGE  1      #密码过期前1天内通知用户
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-18-26-39-image.png)

第二个配置文件为：`/etc/security/pwquality.conf`

```
vi /etc/security/pwquality.conf
```

```
# "N" 处应填写数字
minlen=N              #定义用户密码的最小长度； 
minclass=N            #定义密码必须满足同时有几种字符；
maxrepeat=N           #定义密码中允许几个连续相同的字符；    
maxclassrepeat=N      #定义用户密码连续字符的最大数目；
lcredit=N             #定义用户密码中必须包含多少个小写字母；
ucredit=N             #定义用户密码中必须包含多少个大写字母；1
dcredit=N             #定义用户密码中必须包含多少个数字；1
ocredit=N             #定义用户密码中必须包含多少个特殊字符（除数字、字母之外）；其中 = 1表示，至少有一个
```

配置文件长这样：

第二个配置文件为：`/etc/security/pwquality.conf`

```
vi /etc/security/pwquality.conf
```

```
# "N" 处应填写数字
minlen=N              #定义用户密码的最小长度； 
minclass=N            #定义密码必须满足同时有几种字符；
maxrepeat=N           #定义密码中允许几个连续相同的字符；    
maxclassrepeat=N      #定义用户密码连续字符的最大数目；
lcredit=N             #定义用户密码中必须包含多少个小写字母；
ucredit=N             #定义用户密码中必须包含多少个大写字母；1
dcredit=N             #定义用户密码中必须包含多少个数字；1
ocredit=N             #定义用户密码中必须包含多少个特殊字符（除数字、字母之外）；其中 = 1表示，至少有一个
```

配置文件长这样：

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-18-28-14-image.png" title="" alt="" width="668">

密码策略这里修改后，只对新建用户生效。我们可以新建一个test用户尝试设置其密码。

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-21-18-28-47-image.png)

## <5>ssh 的日志

ssh服务的日志存储于`/var/log/secure`。 `tail -f /var/log/secure` 大家可以自由定制所想查看的日志，例如模拟登录失败，登录成功等不同方式，以观察日志的不同变化。 状态:

- Failed password 为密码错误
- Accept password 为登录成功
- disconnected by user 为断开链接

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-21-18-29-49-image.png" title="" alt="" width="779">

# 九、Apache服务器

Apache是世界使用排名第一的Web服务器软件。它可以运行在几乎所有广泛使用的计算机平台上，由于其跨平台和安全性被广泛使用，是最流行的Web服务器端软件之一。它快速、可靠并且可通过简单的API扩充，将Perl/Python等解释器编译到服务器中。

Apache开源项目:https://projects.apache.org/projects.html?name

## <1>配置文件

Apache主要目录：

**/etc/httpd/conf/httpd.conf**

```bash
/etc/httpd/conf/httpd.conf   #apache的主配置文件
/etc/httpd/                  #apache配置文件的目录
/var/www/                    #apache默认存放网页的目录
```

`/etc/httpd/conf/httpd.conf`文件详解：

```bash
34  ServerRoot "/etc/httpd"                   #定义Apache的配置文件目录
45  Listen 80                                 #定义Apache的端口
69  User apache                               #定义启动用户
70  Group apache                              #定义启动用户组
89  ServerAdmin root@localhost                #定义管理员邮箱
98  #ServerName www.example.com:80            #定义服务器的域名
122 DocumentRoot "/var/www/html"              #定义网站根目录
167 DirectoryIndex index.html                 #定义默认首页文件
```

### 实验1：修改httpd的默认监听端口

**浏览器访问默认http服务是访问80端口，访问https服务默认访问443端口**

```
vi /etc/httpd/conf/httpd.conf
```

修改Listen 80 为8000

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-10-28-52-image.png)

随后重启服务

```
systemctl restart httpd
```

我们访问默认地址，则无法打开页面，需要输入[http://IP:8000](http://IP:8000)

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-10-34-38-image.png)

### 实验2：替换默认页面

`/var/www/html`目录中创建默认页面index.html,内容为“hello world”

```
cd /var/www/html
echo "hello world">>index.html
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-10-41-03-image.png)

客户机浏览器中输入地址，如果成功出现hello world即可。

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-10-41-24-image.png)

### 实验3：替换默认首页名称

修改配置文件`/etc/httpd/conf/httpd.conf`

```
vi /etc/httpd/conf/httpd.conf
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-10-41-56-image.png)

在目录中添加新的index2.html文件,并重启httpd服务

```
echo "no hello world">>index2.html
systemctl restart httpd
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-10-42-27-image.png)

### 实验4：虚拟主机

- 新建一个虚拟机主机配置文件

```
vim /etc/httpd/conf.d/httpd-vhosts.conf
```

- 粘贴以下内容

```bash
NameVirtualHost *:80
<VirtualHost *:80>
    ServerName blog.com
    DocumentRoot /var/www/html
</VirtualHost>

<VirtualHost *:80>
    ServerName app.blog.com
    DocumentRoot /var/www/html/blog
    <Directory "/var/www/html/blog">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

<VirtualHost *:80>
    ServerName test.blog.com
    DocumentRoot /var/www/html/test
    <Directory "/var/www/html/test">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>
```

- 新建web目录

```
mkdir /var/www/html/test
```

- 可以在test目录下放几个网页文件，比如demo.php

```
mv /var/www/html/demo.php /var/www/html/test/index.php
```

- 重启httpd服务

```
systemctl restart httpd
```

- 修改kali中的/etc/hosts文件

```
sudo vim /etc/hosts
```

> 第一列修改为自己centos的ip

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-12-14-10-image.png)

- 打开浏览器测试虚拟主机

```
http://app.blog.com/
http://test.blog.com/
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-12-16-38-image.png)

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-12-16-54-image.png)

## <2>Apache的日志

利用`tail -f /var/log/httpd/*`监控apache日志。

当我们安装并启动Apache后，Apache会自动生成两个日志文件，在linux系统中他们保存在`/var/log/httpd/`下，这两个日志文件分别是访问日志access_log和错误日志error_log。如果使用 SSL 服务的话，还可能存在 ssl_access_log和ssl_error_log 和 ssl_request_log 三种日志文件。

访问日志access_log记录了所有对Web服务器的访问活动，下面是访问日志access_log中的一个标准记录

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-14-42-23-image.png)

192.168.10.110 - - [28/Mar/2022:08:29:09 +0800] "GET /login.php HTTP/1.1" 200 1415 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36"

日志字段所代表的内容如下：

1. 远程主机IP：表明访问网站的是谁
2. 空白(E-mail)：为了避免用户的邮箱被垃圾邮件骚扰，第二项就用“-”取代了
3. 空白(登录名)：用于记录浏览者进行身份验证时提供的名字。
4. 请求时间：用方括号包围，而且采用“公用日志格式”或者“标准英文格式”。 时间信息最后的“+0800”表示服务器所处时区位于UTC之后的8小时。
5. 方法+资源+协议：服务器收到的是一个什么样的请求。该项信息的典型格式是“METHOD RESOURCE PROTOCOL”，即“方法 资源 协议”。
6. 状态码：请求是否成功，或者遇到了什么样的错误。大多数时候，这项值是200，它表示服务器已经成功地响应浏览器的请求，一切正常
7. 发送字节数：表示发送给客户端的总字节数。它告诉我们传输是否被打断（该数值是否和文件的大小相同）。把日志记录中的这些值加起来就可以得知服务器在一天、一周或者一月内发送了多少数据。
8. UA信息：访问者的user-agent信息。

下面是错误日志的格式：

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-14-43-42-image.png)

# 十、NFS服务

在过往的IT体系中，磁盘的性能一直在制约着整体的性能。而诸如于云计算、备份数据等需求往往需要海量的空间。

在实际的场景中，可以将存储分为如下三类：

```
1 单机版存储
2 类私有网盘存储
3 分布式存储
```

单机版存储可以采用的方案如NFS、SMB等服务。

私有网盘存储可以采用FreeNAS、owncloud等方案。

分布式存储方案可以采用ceph、TFS等。

在企业的环境中可以进行针对性的选择，而出于企业备份数据的角度，课程中所讲述的存储方案为单机版与私有网盘的方案。

## <1>NFS简介

NFS（Network File System）即网络文件系统，是FreeBSD支持的文件系统中的一种，它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中，本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件，就像访问本地文件一样。

**服务器将文件或目录远程安装在客户端上，并通过虚拟连接共享访问权限。对于客户端，NFS 像在操作期间访问本地文件一样使用远程服务器文件。**

以下是NFS最显而易见的好处：

- 节省本地存储空间，将常用的数据存放在一台NFS服务器上且可以通过网络访问，那么本地终端将可以减少自身存储空间的使用。
- 一些存储设备如软驱、CDROM和Zip（一种高储存密度的磁盘驱动器与磁盘）等都可以在网络上被别的机器使用。这可以减少整个网络上可移动介质设备的数量。

**需要特别强调，NFS服务用于Linux类的主机间的文件共享，当需要与windows生态进行访问时，需要采用SMB协议。**

## <2>NFS服务搭建

在NFS的服务中，主要依赖于nfs-utils与rpcbind的来进行服务。

在centos中，使用如下命令安装所需服务

```
yum -y install rpcbind nfs-utils
```

关于rpcbind的作用

> RPC(Remote Procedure Cal)即远程过程调用，是分布式应用的基础，即允许计算机远程调用网络上其他计算机的程序。RPC通常由提供RPC服务的服务端和使用RPC服务端的客户端组成。
> rpcbind(亦称rpc.portmap, port mapper, portmap)是一个运行在网络节点(提供其他RPC服务)上的RPC服务。rpcbind是RPC服务的管理者。当一个RPC服务端开启时，它会告诉rpcbind它提供的RPC服务的端口号、协议类型(TCP/UDP)、过程调用服务号和版本号键值对。当RPC客户端请求指定过程调用号和版本号的RPC服务时，首先必须通过rpcbind获取端口号和协议类型。rpcbind服务必须在其他RPC服务端之前开启。
> 
> 通俗的来说，rpcbind是NFS中 用来进行消息通知的服务。

**所以在NFS的服务的启动中，启动rpcbind后再启动nfs服务。**

```
systemctl start rpcbind
systemctl start nfs-server
systemctl enable rpcbind
systemctl enable nfs-server
```

查看rpc服务的注册情况，可使用rpcinfo的指令进行查看。

```
rpcinfo -p localhost
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-15-27-53-image.png)

## <3>NFS的配置文件

NFS服务的配置文件为/etc/exports

建立分享的文件如下

```
mkdir /share1
mkdir /share2
```

编辑/etc/exports，输入如下内容：

```
/share1 *(sync,ro) 192.168.229.130(sync,rw)
/share2 192.168.229.0/24(sync,ro)
```

编辑完成后，需要运行exportfs重新发布所共享的目录。（先exportfs -r 重新读取配置文件）

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-15-28-34-image.png)

**<u>如果需要重启服务，建议先重启rpcbind再重启NFS服务。</u>**

配置文件的含义如下：

输出"/share1"目录，对所有主机可读，对IP地址为192.168.229.130的主机可读可写。

输出"/share2"目录，对192.168.229.0/24网络内的所有主机可读。

配置文件每行分为两段：第一段为共享的目录，使用绝对路径，第二段为客户端地址及权限。

```
地址可以使用完整IP或网段，例如10.0.0.8或10.0.0.0/24，10.0.0.0/255.255.255.0当然也可以地址可以使用主机名，DNS解析的和本地/etc/hosts解析的都行，支持通配符，例如：*.fsec.io  
 权限有：  
·  rw：read-write，可读写； 
·  ro：read-only，只读；  
·  sync：文件同时写入硬盘和内存；  
·  async：文件暂存于内存，而不是直接写入内存；  
·  no_root_squash：NFS客户端连接服务端时如果使用的是root的话，那么对服务端分享的目录来说，也拥有root权限。  
·  root_squash：NFS客户端连接服务端时如果使用的是root的话，那么对服务端分享的目录来说，拥有匿名用户权限，通常他将使用nobody或nfsnobody身份；  
·  all_squash：不论NFS客户端连接服务端时使用什么用户，对服务端分享的目录来说都是拥有匿名用户权限；  
·  anonuid：匿名用户的UID值，通常是nobody或nfsnobody，可以在此处自行设定；  
·  anongid：匿名用户的GID值。
```

## <4>客服端访问

### 1.showmount

showmount -e 显示本地NFS服务器中的共享列表

```
showmount -e
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-15-29-22-image.png)

showmount -e IP 显示指定NFS服务器中的共享列表

```
showmount -e IP
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-15-29-53-image.png)

### 2.mount

mount命令用于挂载磁盘，在nfs的服务中，需要使用mount -t nfs 或者mount.nfs的指令进行指定挂载的类型。

使用挂载前先在客户端创建挂载点。（就是创建目录）

```
mkdir -p ~/test/share1
mkdir -p ~/test/share2
```

- 使用mount -t 指令挂载远程主机的目录

```
sudo mount -t nfs 192.168.127.155:/share1 ~/test/share1
sudo mount -t nfs 192.168.127.155:/share1 ~/test/share2
```

- 在centos上的share1目录下创建新文件

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-15-47-16-image.png)

回到kali，可以看到kali上的share1目录下的文件也更新了

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-15-47-48-image.png)

## <5>备份数据的方案

假设现今我们在IDC的网络中，搭建了一台NFS的服务器用于给业务主机提供数据备份的服务。那么此时我们的需求可以梳理出大致需要完成以下三点的需要：

1 如果客户端重启后，那么挂载的连接将会失效，为此需要拥有自动挂载的方案。

2 备份的所拷贝的文件或文件夹时，需要采用时间戳进行命名，以便用于区分。

3 系统中哪些文件需要备份？

### 5.1 客户端自动挂载NFS

在服务器中，通过如下的命令，我们重新调整NFS的配置。

```
mkdir /backup
vi /etc/exports
cat /etc/exports
/backup 192.168.229.0/24(sync,rw,no_root_squash)
exportfs -r
exportfs
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-15-57-47-image.png)

在客户机中，可通过使用rc.local的方式实现开机自动挂载。（rc.local 是启动加载文件）

在/etc/rc.local文件中添加如下内容：

```
mount -t nfs 192.168.229.135:/backup  /mnt/backup
#将centos的/backup 挂载到kali的/mnt/backup
```

随后创建挂载点，并给/etc/rc.local执行权限。

```
mkdir /mnt/backup
chmod +x /etc/rc.local
mount -t nfs 192.168.229.135:/backup  /mnt/backup
```

重启主机后，可进入/mnt/backup目录中查看是否存在测试的文件即可。

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-15-58-20-image.png)

### 5.2 通过计划任务自动挂载备份数据

**在客户机进行**!首先我们先编写备份的脚本，以备份passwd文件为例：

```
vi  bash.sh
```

```
#!/bin/bash
date="$(date +%F)"
cp /etc/passwd /mnt/backup/pass_$date
```

```
sh bash.sh
```

随后可通过计划任务进行配置周期性的运行脚本即可。

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-22-15-59-16-image.png)

- **哪些文件需要备份**

数据无价！！！

数据库、web代码、web所上传的文件、日志等。

- **错误的NFS配置**

第一，如果NFS暴露在公网中，虽然只给予了只读权限，那么外网主机通过访问共享即可得到敏感的数据。

第二，NFS在位于内网中的情况，那么当攻击者拿到其中一台主机的权限后，可通过访问备份的目录进入到数据集中的区域。

第三，如果将敏感的目录共享出去，攻击者有可能查看到/etc/shadow或者编辑密钥实现攻击。

# 十一、Shell脚本

## <1>shell是什么？

Shell 是一个应用程序，它连接了用户和 Linux 内核，让用户能够更加高效、安全、低成本地使用 Linux 内核，这就是 Shell 的本质。

用户可以用shell来启动 挂起 停止 甚至编写一些程序。

Shell 本身并不是内核的一部分，它只是在内核的基础上编写的一个应用程序，它和 QQ、迅雷、Firefox 等其它软件没有什么区别。

Shell 也是一种编程语言，它的编译器（解释器）是 Shell 这个程序。我们平时所说的 Shell，有时候是指连接用户和内核的这个程序，有时候又是指 Shell 编程。Shell 主要用来开发一些实用的、自动化的小工具，而不是用来开发具有复杂业务逻辑的中大型软件。

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-23-10-50-15-image.png)

## <2>shell脚本的执行方式

- 用直接用脚本名称执行
  
  ![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-23-11-18-29-image.png)

使用shell解释器执行

- sh执行
- bash执行

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-23-11-17-51-image.png)

shell脚本的格式要求

脚本以`#!/bin/bash` 开头

脚本要有可执行权限 chmod +x （用脚本名称执行时，不会报错）

### 编写一个shell脚本输出hello world

```
mkdir shell
cd shell
vim hello.sh
#输入
echo "hello world~~"
```

**查看权限：**

```
┌──(kali㉿kali)-[~/shellProgram]
└─$ ll
total 4
-rw-r--r-- 1 kali kali 31 Aug 31 22:01 hello.sh
```

**执行：**

```
┌──(kali㉿kali)-[~/shellProgram]
└─$ ./hello.sh
zsh: permission denied: ./hello.sh
```

**赋予执行权限运行：**

```
chmod +X hello.sh
./hello.sh
```

**不赋予执行权限运行程序：**

```
chmod -x hello.sh
sh hello.sh
```

总结：运行shell的两种方式

- 赋予执行权限 chmod +x
- 不赋予执行权限 sh 运行

## <3>shell的变量

### 1.shell变量的介绍

Linux shell中的变量分为 **系统变量** 和**用户自定义变量,**系统变量就是系统自带的变量。

系统变量：HOME PWD SHELL USER 例如echo $HOME

- 可以使用env命令查看这些系统变量

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-23-11-19-50-image.png)

### 2.shell变量的定义

**基本语法：**

1.定义变量: 变量名=值

2.撤销变量unset 变量值

3.声明静态变量（readonly） 注意：不能unset

变量调用：

- $A
- ${A}

**注意：**

1.变量名称可以以字母数字和下划线组成，但是不能以数字开头。 例如：~~3A=200~~

**2.等号两侧不能有空格**

```bash
A=100 #正确
A =100 #错误
```

3.变量名字一般习惯为大写

例子：

- 定义变量A

```
#!/bin/bash
#定义变量A
A=100
echo $A

#虽然在双引号内，但$A它不是字符串
echo "A=$A"   
```

- 撤销变量A

```
#!/bin/bash
#定义变量A
A=100
echo $A

#虽然在双引号内，但$A它不是字符串
echo "A=$A" 
unset A
echo "A=$A" 
```

- 声明静态变量

```
readonly B=1
unset B
echo $B
```

```
1.sh: 10: unset: B: is read only
```

### 3.预定义变量

介绍：shell设计者已经定义好的变量，可以在shell脚本中使用

基本语法：

- $$ 当前进程的进程号PID
- $! 后台运行的最后一个进程的进程号PID
- <u><mark>$? 最后一次执行命令的返回状态，如果是0 证明上一个命令正确执行，如果非0 则证明 的上一个命令执行错误</mark></u>
- `$0`：当前脚本的名称。﻿﻿
- `$#`：传递给脚本的命令行参数的个数。﻿
- `$*`：所有命令行参数组成的单个字符串。﻿
- `$@`：所有命令行参数组成的一个列表或数组。
- $1,$$2,...:存储命令行参数$

## <4>运算符

基本语法：

- “((运算式))” 或 “[运算式]” 或 expr m + n //expr是 expression表达式的缩写
- expr 运算符间要有空格
- expr 乘`\*` 除`/` 取余 `%`

**案例：** 计算 (2 + 3) x4的 值

```sh
#!/bin/bash
#第一种方式 不推荐
RES1=$(((2+3)*4))
echo "$RES1"

#a第二种方式 推荐使用
RES2=$[(2+3)*4]

#第三种方式  不推荐
RES3=`expr 2 + 3` 
RES4=`expr $RES3 * 4`
echo $RES3
echo $RES4
```

```
#!/bin/bash
RES2=$[(2+3)*4]
echo $RES2
```

## <5>流程控制

### 条件测试

```
test 条件表达式
或者
[ 条件表达式 ]
```

#### 文件测试

- -d 测试是否为目录（Directory）
- -f 测试是否为文件 （File）
- -e 测试目录或者文件是否存在 （Exist）
- -r 测试当前用户是否可读
- -w 测试当前用户是否可写
- -x 测试当前用户是否可执行

例子：

- 测试test是否为目录

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-23-15-30-42-image.png" title="" alt="" width="568">

测试test.txt是否为文件

```
#!/bin/bash
[ -f /root/test.txt ]

echo $?
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-23-15-31-12-image.png)

#### 数值比较

| 判断条件 | 意义                            |
| ---- | ----------------------------- |
| -lt  | less than小于 <                 |
| -le  | less than or equal小于等于 <=     |
| -eq  | equal等于 =                     |
| -gt  | greater than 大于>              |
| -ge  | greater than or equal 大于等于 >= |
| -ne  | not equal不等于                  |

例子：

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-23-15-31-55-image.png" title="" alt="" width="452">

#### 字符串比较

- = 第一个字符串和第二个字符串相同
- != 第一个字符串和第二个字符串不同
- -z 检查字符串是否为空

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-23-15-32-37-image.png" title="" alt="" width="455">

#### 逻辑判断

- && 前后两个条件都成立，整个测试命令才返回0
- || 前后两个条件中，有一个成立，整个测试命令返回0
- ！当指定条件不成立，测试命令才返回0

> 执行命令时：
> 
> - && 代表左边命令执行成功，再执行右边的命令
> - || 代表左边命令执行失败，再执行右边的命令

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-23-15-33-36-image.png" title="" alt="" width="540">

## <6>if语句

```sh
if [ condition ]
then
        command
        command
fi
```

[ condition ] 注意condition前后要有空格

**案例：判断OK 是否等于OK**

```sh
#!/bin/bash

if [ "OK" = "OK" ]
then
        echo "yes"
else
        echo "no"
fi
```

**案例：23是否大于22**

```sh
#!/bin/bash
if [ 23 -ge 22 ]
then
    echo "大于"
fi    
```

**案例：判断/home/kali/1.txt 文件是否存在**

```sh
#!/bin/bash
if [ -f /home/kali/1.txt ]
then
    echo "存在"
else 
    echo "不存在"
fi    
```

**案例：输入的参数大于等于60 ，输出及格，如果小于60 则输出 不及格**

```sh
#!/bin/bash

if [ $1 -ge 60 ]
then
        echo "及格"
elif [ $1 -lt 60 ]
then
        echo "不及格"
fi
```

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-23-15-34-55-image.png" title="" alt="" width="407">

case语句

基本语法：

```
case $变量名  in
"值1")
如果变量的值等于值1，则执行程序1
;;
"值2")
如果变量的值等于2，则执行程序2
;;
"值3")
如果变量的值等于3，则执行程序3
;;
*)
如果变量的值都i不是以上的值，则执行此程序
esac
```

案例：参数是1的时候 输出 ”周一“ 是2的时候就输出”周二“ 其他的情况输出 ”other“

```sh
#!/bin/bash
case $1 in
        "1")
                echo "周一"
                ;;
        "2") 
                echo "周二"
                ;;
        *)
                echo "其他。。。。"
                ;;
esac
```

<img src="file:///C:/Users/ZhuanZ/AppData/Roaming/marktext/images/2026-07-23-15-35-48-image.png" title="" alt="" width="397">

## <7>for循环

列表for循环：用于将一组命令执行**已知的次数**，下面给出了for循环语句的基本格式：

第一种方式：

```sh
for variable in a b c
     do
         command
         command
     done
```

第二种方式：

```
for (( i=1;i<=5;i++))
    do
        echo $i
    done
```

**案例1：打印命令行输入的所有参数 `$*`**

注意： **$*把输入的参数当作一个整体 所以只会输出一句**

```sh
#!/bin/bash
for i in "$*"
    do
        echo "你输入的是：$i"
done        
```

运行：`sh 9.sh 1,2,23.44 44 32 k j kl`

**案例2：**打印命令行输入的所有参数 `$@`

注意： $@把输入的参数区别对待，有几个参数就会输出几句

```sh
#!/bin/bash
for i in "$@"
    do
        echo "你输入的是：$i"
done    
```

**案例3：求从1加到100 的和**

```sh
#!/bin/bash
SUM=0
for ((  i=1; i<=100; i++  ))
do
    SUM=$[$SUM + $i]
done
echo "1-100的和是$SUM"
```

**案例3：求从1加到 “ 你输入的变量” 的和**

```sh
#!/bin/bash
SUM=0
for ((  i=1; i<=$1; i++  ))
do
    SUM=$[$SUM + $i]
done
echo "1-100的和是$SUM"
```

- **通过一个用户名文件，批量创建用户**

```bash
#!/bin/bash

USERLIST=$(cat /root/users.txt)

for NAME in $USERLIST
do
        useradd $NAME
done
```

- **根据ip地址列表，检查主机的状态**

```bash
#!/bin/bash

IPLIST=$(cat /root/ips.txt)

for IP in $IPLIST
do
        ping -c 3 -i 0.2 -W 3 $IP &> /dev/null
        if [ $? -eq 0 ]
        then
                echo "$IP is up."
        else
                echo "$IP is down."
        fi
done
```

## <8>while循环

**特点：**条件为真就进入循环；条件为假就退出循环

**注意中括号有空格**

```shell
while [ 表达式 ]
    do
        command...
    done
```

**案例：**从命令行输入一个数n 统计从1 +....+n的值

```sh
#!/bin/bash
SUM=0
i=0
while [ $i -le $1 ]
do
    SUM=$[$SUM+$i]
    i=$[$i+1]
done
echo $SUM
```

## <9>read命令

基本语法：

-p: 指定读取值时的提示符

**案例：** 读取控制台输入的一个NUM1值

```sh
#!/bin/bash
read -p "请输入一个数"  NUM1
echo "你输入的是$NUM1"
```

# Docker

> 需要理解的概念
> 
> - docker源
> - 镜像
> - 容器

## <1>Docker是什么

> 迷你的虚拟机

Docker是一个开源的平台，它使用容器化技术来打包应用程序及其所有依赖项（库、系统工具、代码等）到一个标准化的、可执行的容器中。这使得开发人员能够快速构建、测试和部署应用程序，并且保证应用程序在任何环境中都能一致地运行，从而简化了软件的开发和交付流程，并提高了效率

## <2>Docker和虚拟机的区别

Docker与虚拟机的主要区别在于抽象层次：虚拟机在硬件层面进行隔离，模拟整个计算机系统并运行独立的操作系统（Guest OS），而Docker则在应用层面隔离，容器共享宿主机内核，省略了Guest OS。这使得Docker更轻量、启动更快、资源利用率更高，适合微服务和DevOps，而虚拟机则提供更强的系统级隔离和多操作系统支持，适合需要完全隔离或运行不同操作系统的场景。﻿

## <3>Docker命令

> 命令大致分为三种
> 
> - 对镜像操作
> - 对容器操作
> - 其他

### 1.docker search

- 从镜像源中搜索镜像

例子：

- 搜索一个nginx镜像

```
docker search nginx
```

### 2.docker pull

- 下载镜像

```
docker pull nginx
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-10-17-44-image.png)

### 3.docker images

- 列出本地主机上的镜像

```
docker images
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-10-18-33-image.png)

各个选项说明:

- **REPOSITORY：**表示镜像的仓库源
- **TAG：**镜像的标签
- **IMAGE ID：**镜像ID
- **CREATED：**镜像创建时间
- **SIZE：**镜像大小

### 4.docker run

创建一个新的容器并运行一个命令,其中常用的参数如下：

```
-d: 后台运行容器，并返回容器ID；
-i: 以交互模式运行容器，通常与 -t 同时使用；
-P: 随机端口映射，容器内部端口随机映射到主机的端口
-p: 指定端口映射，格式为：主机(宿主)端口:容器端口
-t: 为容器重新分配一个伪输入终端，通常与 -i 同时使用；
--name="fsec": 为容器指定一个名称；
-v: 绑定一个卷;
--net="bridge": 指定容器的网络连接类型，支持 bridge/host/none/container: 四种类型；
```

- 使用镜像nginx:latest以后台模式启动一个容器,并将容器命名为fsec1.

```
docker run --name fsec1 -d nginx:latest
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-10-19-27-image.png)

- 使用镜像 nginx:latest，以后台模式启动一个容器,**将容器的 80 端口映射到主机的 8888 端口**,主机的目录 /data 映射到容器的 /data,,同时容器命名为fsec3.

> **想在外部访问到容器里的应用，需要使用端口映射功能**

```
docker run --name fsec2 -p 8888:80 -v /data:/data -d nginx:latest
```

- 使用镜像nginx:latest以后台模式启动一个容器,并**将容器的80端口映射到主机随机端口,**同时容器命名为fsec2.

```
docker run --name fsec3 -P -d nginx:latest
```

### 5.进入容器执行命令行

```
docker exec -it fsec1 /bin/bash
```

### 6.查看容器

```
docker container ls -a
```

### 7.docker rm / rmi

rm：删除容器

```
 docker rm 35f76425aafe
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-10-23-34-image.png)

- 强制删除，使用 -f

```
docker rm -f 6afa089e8964
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-10-24-04-image.png)

 rmi：删除镜像

```
 docker rmi 4a86014ec699
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-10-24-46-image.png)

### 8.文件传递

从主机复制到容器

```
docker cp 主机路径 容器ID:容器路径
docker run --name fsec-nginx1 -P -d nginx:latest
docker cp /etc/passwd fsec-nginx1:/opt
docker exec -ti fsec-nginx1 cat /opt/passwd
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-14-18-46-image.png)

从容器复制到主机

```
docker cp 容器ID:容器路径 主机路径
docker cp fsec-nginx1:/opt/passwd /opt
cat /opt/passwd
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-14-20-10-image.png)

### 9.docker commit

从容器创建一个新的镜像，常用参数如下：

```
-a :提交的镜像作者；
-c :使用Dockerfile指令来创建镜像；
-m :提交时的说明文字；
-p :在commit时，将容器暂停。
[root@C1 ~]# docker ps
[root@C1 ~]# docker exec -ti fsec-nginx1 /bin/bash
root@1df5bff6cad7:/# ls /opt
root@1df5bff6cad7:/# exit
[root@C1 ~]# docker commit -a "fsec.io" -m "fsec-nginx" 1df5bff6cad7 fsec/v1
[root@C1 ~]# docker commit -a "fsec.io" -m "fsec-nginx" 1df5bff6cad7 fsec:v1
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-14-22-14-image.png)

docker run --name fsec-v1 -p 9999:80 -d fsec:v1
docker exec fsec-v1 ls /opt

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-14-22-41-image.png)

### 10.docker save/load

docker save 将指定镜像保存成 tar 归档文件，通过-o指定输出到的文件。

```
[root@C1 ~]# docker save -o fsec_v1.tar fsec:v1
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-14-23-18-image.png)

docker load :导入使用docker save命令导出的镜像，通过-i 指定导入的文件。

```
docker rm -f $(docker ps -a -q)
docker rmi xxx
docker images
docker load -i fsec_v1.tar
```

![](C:\Users\ZhuanZ\AppData\Roaming\marktext\images\2026-07-24-14-23-48-image.png)
