# 1.1 系统管理类命令

在计算机发展初期，计算机之庞大以吨为计。因此计算机都是放到一个单独的房间中，人们在另一个地方通过一定的方式（设备）去操控计算机，操控计算机的这个设备被称为终端，也叫终端机。终端其实就是一种输入输出设备，本身并不提供运算处理功能。&#x20;

后来随着个人计算机的普及，终端的含义也慢慢出现了变化。因为个人计算机不再需要一个额外的终端来操作计算机，所有操作都在个人计算机上完成了。但是，计算机操作系统中已有的终端设计却保留了下来，并以终端模拟器（Terminal Emulator）的形式出现。这些终端模拟器被简称为「终端」。 如今，用户主要通过图形化 shell 界面与计算机交互，如 MacOS 操作系统。

更多 shell 介绍和使用，参见[1.3 shell 脚本编程](/study-manual/0.-linux-commands/1.-bash-introduce.md)章节中的内容。

本节的基础系统管理类命令以 CentOS Linux 8 为例。

<div align="left"><figure><img src="/files/WPuKK78QE00e7VjbWmtq" alt="" width="150"><figcaption><p>Tux，Linux 的吉祥物</p></figcaption></figure></div>

## 主机名称

在大多数 Linux 发行版中，都使用`hostname`命令查看或更改主机名。主机名用于网络中的计算机标识。<mark style="color:red;">**修改主机名操作需要重新登陆后才能生效。**</mark>修改主机名称方法如下：

```bash
[zhangzh@node01 ~]$ hostnamectl
   Static hostname: node01
         Icon name: computer-server
           Chassis: server
        Machine ID: 6c1247f5013f4ea08698f184fd35efb8
           Boot ID: 831d4163ee26402e88b8325ef19b406c
  Operating System: CentOS Linux 8
       CPE OS Name: cpe:/o:centos:centos:8
            Kernel: Linux 4.18.0-240.el8.x86_64
      Architecture: x86-64
[zhangzh@node01 ~]$ hostnamectl set-hostname newname
```

{% hint style="info" %}
在 Linux 系统中，用户账户主要分为两大类：普通用户和超级用户/管理员，后者通常特指 root 用户。root 对系统拥有绝对权力；而普通用户只对个人目录下的文件拥有完全控制权。

<mark style="color:red;">直接以管理者身份（root）操作 shell 是危险的，所以计算机用户通常以普通用户登陆。</mark>

示例代码中`[zhangzh@node01 ~]$`分别表示以用户名为`zhangzh`的用户登陆主机名为`node01`的主机。

当`root`用户登陆时`$`符号会变为`#`符号，以示区分。
{% endhint %}

## 电源管理

服务器和电脑都是计算机的一种形式，都可以开关机和重启：

**重启命令 e.g.**

```bash
[zhangzh@node01 ~]$ bash          # 仅适用于账户的重启
[zhangzh@node01 ~]# reboot now    # 适用于对服务器的重启
```

**关闭命令 e.g.**

```bash
[zhangzh@node01 ~]# shutdown now    # 立刻关机
[zhangzh@node01 ~]# shutdown 20:30  # 今晚八点半关机
[zhangzh@node01 ~]# shutdown +20    # 20min后关机
```

## 密码设置

**passwd命令** 设置用户的认证信息，包括用户密码、密码过期时间等。只有 root 用户可以指定用户名称或者修改密码，普通用户只能修改自己的密码。

修改其他用户的密码方式参考本章[用户管理](#yong-hu-guan-li)一节；找回 root 密码的方法参考[这篇博客](http://t.zoukankan.com/canyezhizi-p-13574958.html)。

## 远程控制

**ssh命令** 用来远程连接服务器。e.g.

```bash
[zhangzh@node01 ~]$ ssh -p 8022 zhangzh@222.2.2.102    # -p:指定端口号
```

需要启动 X11 服务（即调用 GUI）时需要添加`-XY` 参数。

在 MacOS 中开启 X11 转发服务方法可以参考：[1.5 MacOS Ventura](/study-manual/0.-linux-commands/3.-mac-terminal.md#shi-yong-xquartz-diao-yong-gui-jie-mian)。&#x20;

每次输入密码登陆未免太过麻烦，因此，可以在值得信任的计算机上设置免密登陆：

在可以信任的计算机上执行`ssh-keygen`命令，生成 ssh 钥匙。MacOS 中钥匙的路径存放在`.ssh/`。e.g.

```bash
local$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Created directory '/home/user/.ssh'.
Enter passphrase (empty for no passphrase):    <====空格
Enter same passphrase again:                   
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:47VkvSjlFhKRgz/6RYdXM2EULtk9TQ65PDWJjYC5Jys user@local
The key's randomart image is:
+---[RSA 2048]----+
|       ...o...X+o|
|      . o+   B=Oo|
|       .....ooo*=|
|        o+ooo.+ .|
|       .SoXo.  . |
|      .E X.+ .   |
|       .+.= .    |
|        .o       |
|                 |
+----[SHA256]-----+
```

接下来将公钥内容拷贝至需要控制的服务器即可。e.g.

```bash
local$ ssh zhangzh@222.19.64.20 -p 8022 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub
```

**配置登陆服务器名称：**

将远程服务器命名为`klcr`， 在配置文件中`.ssh/config`写入：

```bash
Host klcr
	Hostname 222.19.64.20
	Port 8022
	User zhangzh
	IdentityFile ~/.ssh/id_rsa
```

至此，就完成了服务器的别名配置，输入`ssh klcr`即可免密访问服务器。&#x20;

在终端中上传和下载本地或服务器的文件方法参见[跨服务器传输文件](/study-manual/0.-linux-commands/1.2-wen-jian-guan-li-lei-ming-ling.md#fu-zhi-yi-dong-zhong-ming-ming-shan-chu)章节内容。

## 服务管理

#### **启动服务**

不同系统的服务启动指令略有差异，本系统使用`systemctl start git`启动。e.g.

```shell
[zhangzh@node01 ~]$ systemctl start yum
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to start 'yum.service'.
Authenticating as: root
```

#### 暂停服务

* 标准安全的暂停：

```shellscript
[zhangzh@node01 ~]$ systemctl stop <服务名>
```

* 永久禁用：

```shellscript
[zhangzh@node01 ~]$ systemctl disable <服务名>
```

## 用户管理

用户管理涉及到<mark style="color:purple;">**组**</mark>与<mark style="color:purple;">**用户**</mark>以及权限的概念。通常，普通用户只对自己的文件具有完整权限，同组用户拥有相对完整的权限，对组外（其他）用户不具备任何权限。权限控制命令参见[1.2 文件管理类命令](/study-manual/0.-linux-commands/1.2-wen-jian-guan-li-lei-ming-ling.md#quan-xian)。

**useradd命令** 建立用户帐号。

**usermod命令** 修改用户帐号。

**userdel命令** 删除用户帐号。

**组管理命令：**

```shell
# groupadd groupname                 # 新建用户组
# groupadd -n groupname newgroupname # 修改用户组名称
# groupdel groupname                 # 删除用户组
```

**用户管理命令：**

```shell
# useradd username                   # 新建用户
# useradd -d /home/users username    # 指定根目录创建用户
# useradd -g groupname username      # 新建用户并指定用户组
# usermod -g groupname username      # 为新建用户指定用户组
# passwd username                    # 修改用户密码
# userdel -r username                # 删除用户及主目录
# whois username                     # 查询用户
```

{% hint style="danger" %}
当创建用户时出现 Creating mailbox file: File exists 的错误。请直接删除 /var/spool/mail/ 和 /home 下的之前存在的用户文件，删除后就能重建成功。
{% endhint %}

<details>

<summary>e.g. 一个简单的 adduser 流程</summary>

```sh
[root@node02 l]# useradd -d /home/users/l/lixl lixl
[root@node02 l]# ls
lixl
[root@node02 l]# passwd lixl
Changing password for user lixl.
New password: 
BAD PASSWORD: The password fails the dictionary check - it is too simplistic/systematic
Retype new password: 
passwd: all authentication tokens updated successfully.
[root@node02 l]# usermod -g ybj lixl
[root@node02 l]# ll
total 4
drwx------ 3 lixl ybj 4096 Aug  1 13:40 lixl
[root@node02 l]#
```

</details>

{% hint style="info" %}
**su命令**（switch uesr）用于变更使用者身份。常见用法如：`su username`或者`su -c command username`，其含义分别是切换至用户名为`username`的账户和切换至`username`的账户后执行命令后退出该账户。
{% endhint %}

## **进程管理**

**top命令** 实时查看系统的运行情况。

`top`界面支持个性化：按`z`更改界面颜色，按 `shift+z`，依次点按`S`和数字`0-7`可以更改对应位置的字体颜色，按`t`和`m`可以切换显示 CPU、GPU 的占用情况，按回车后按`W`保存。

{% tabs %}
{% tab title="top 命令" %}

```bash
:17 up 10 days, 16:30,  6 users,  load average: 0.00, 0.00, 0.00
Tasks: 1162 total,   1 running, 1161 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem : 257284.2 total, 231838.1 free,   3752.3 used,  21693.8 buff/cache
MiB Swap:  30517.0 total,  30517.0 free,      0.0 used. 251483.6 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND              
     12 root      20   0       0      0      0 I   0.3   0.0  35:25.93 rcu_sched            
   2988 rngd      20   0  376296   8608   5492 S   0.3   0.0   4:53.00 rngd                 
2070853 zhangzh   20   0  276376   6572   4604 R   0.3   0.0   0:00.36 top                  
      1 root      20   0  243500  11876   8304 S   0.0   0.0   1:01.35 systemd              
      2 root      20   0       0      0      0 S   0.0   0.0   0:00.86 kthreadd             
      3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp               
      4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_par_gp           
      6 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/0:0H         
```

{% endtab %}

{% tab title="w 命令" %}

```bash
[zhangzh@node01 ~]$ w 
 14:09:47 up 1 day,  1:23,  5 users,  load average: 296.24, 296.26, 296.21
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
lixl     pts/1    222.19.66.192    10:35    1:48m  0.70s  0.62s vim shell_020.sh
lixl     pts/2    222.19.66.192    10:38    2:21m  0.10s  0.10s -bash
lixl     pts/3    222.19.66.192    13:28   33.00s  0.11s  0.03s vim shell_021
zhangzh  pts/4    172.29.85.47     13:44    3.00s  0.11s  0.04s wbash
```

{% endtab %}

{% tab title="美化后的 top 界面" %}

```bash
top - 19:18:49 up 6 days, 11:51,  6 users,  load average: 105.10, 104.52, 90.03
Tasks: 1329 total, 106 running, 1222 sleeping,   1 stopped,   0 zombie
%Cpu(s):  93.3/0.5    94[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||     ]
MiB Mem :  6.9/257284.2 [|||||                                                                    ]
MiB Swap:  5.5/30517.0  [||||                                                                     ]
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                     
 137605 liulw     20   0  116184  48608   4556 R  99.7   0.0   8439:25 ./corsika74100Linux_QGSJET_+
 151409 liulw     20   0  116184  48628   4572 R  99.7   0.0   8437:22 ./corsika74100Linux_QGSJET_+
 400337 liulw     20   0  116184  44392   4440 R  99.7   0.0  21:43.59 ./corsika74100Linux_QGSJET_+
 410036 liulw     20   0  116184  44580   4624 R  99.7   0.0  21:43.37 ./corsika74100Linux_QGSJET_+
 449661 liulw     20   0  116184  27928   4468 R  99.7   0.0  21:42.83 ./corsika74100Linux_QGSJET_+
 502299 liulw     20   0  116184  27284   4052 R  99.7   0.0  21:41.53 ./corsika74100Linux_QGSJET_+
```

{% endtab %}
{% endtabs %}

**w命令** 显示登陆系统的用户列表，用户正在执行的进程，登陆地点，登陆时间等等信息。还可用于查看系统时间，这一点和`uptime`作用一致。更多关于时间的命令可以参考[附录](#time-ming-ling-yong-yu-tong-ji-gei-ding-ming-ling-suo-hua-fei-de-zong-shi-jian)。该命令参数如下：

```bash
 -f, --from          显示用户从哪登录；
 -i, --ip-addr       显示IP地址而不是主机名（如果可能）
     --help          显示此帮助并退出
```

<mark style="color:green;">**jobs命令**</mark> <mark style="color:green;"></mark><mark style="color:green;">显示作业的状态，如列出活动和停止的作业。</mark>

`jobs`常用参数是`jobs -l`，以包含`pid`的形式展示进程。需要注意的是`jobs`只能查看当前账户的进程，诸如`nohup`之类的命令，在重新登陆后`jobs`可能无法查询到该进程，这时候建议使用`ps`命令来管理。

<mark style="color:green;">**ps命令**</mark><mark style="color:green;">（process status）报告当前系统的进程状态。</mark>

搭配`kill`指令随时中断、删除不必要的程序。`ps`是最基本和强大的进程查看命令。如`ps -aux`配合`grep`命令查找需要的进程，并打印 ID 号和所属用户。

**pstree命令** 以一种优雅的方式展示进程树。

#### 当进程严重影响到服务器的运行状态时，可以指定结束特定用户的特定进程。

**kill命令** 通过进程 ID （Progress ID, PID）关闭进程。<mark style="color:green;">使用</mark><mark style="color:green;">`kill -9`</mark><mark style="color:green;">命令立即杀死指定 PID 的进程。</mark>使用`ps`等命令配合`grep`来查找进程 ID。

**killall命令** 关闭指定用户名称的所有进程。

**pkill命令** 按照进程名杀死进程。`pkill`和`killall`应用方法差不多，也是直接杀死运行中的程序；如果想杀掉单个进程，用`kill`。

```shell
# pkill -u username
# killall -u username
```

<mark style="color:green;">**进程中无法输入 kill 时，使用如下命令中止或挂起进程。**</mark>

```shell
ctrl c     # 中断进程，如无法中断时
ctrl z     # 将进程调入后台，可以使用fg和bg命令前台或后台继续该任务
ctrl \     # 直接退出当前程序
```

{% hint style="danger" %}
当需要`kill`某项进程时，请先关闭该进程之前的进程，否则可能会报错。如`nohup ping`，应先`kill ping`，再`kill nohup`。
{% endhint %}

## 配置文件

环境变量（environment variable）是用来存储有关 shell 会话和工作环境的信息的一种特性。

这项特性允许在内存中存储数据以便程序或 shell 中运行的脚本能够轻松访问到它们。这也是存储持久数据的一种简便方法。

{% hint style="warning" %}
变量名区分大小写。所有的环境变量名均使用大写字母，这是 bash shell 的标准惯例。如果是个人创建的局部变量或是 shell 脚本，请使用小写字母，这能够避免重新定义系统环境变量可能带来的灾难。
{% endhint %}

{% hint style="danger" %} <mark style="color:red;">**变量名、等号和值之间没有空格，这一点非常重要。如果在赋值表达式中加上了空格，bash shell 就会把值当成一个单独的命令**</mark>
{% endhint %}

根据作用域的不同，环境变量分为两种：<mark style="color:purple;">**全局环境变量**</mark>和<mark style="color:purple;">**局部环境变量**</mark>**。**&#x4F7F;用`echo`显示变量的值。在这种情况下引用某个环境变量的时候，必须在变量前面加上一个美元符`$`  e.g.

```bash
[zhangzh@node01 sshpass-1.08]$ echo $HOME
/home/users/z/zhangzh
```

在变量名前加上`$`可不仅仅是要显示变量当前的值。它能够让变量作为命令行参数。e.g.

```bash
[zhangzh@node01 sshpass-1.08]$ ls $HOME
asgamma  bin  grb  other  practice  software  wl
[zhangzh@node01 sshpass-1.08]$ ls /home/users/z/zhangzh/
asgamma  bin  grb  other  practice  software  wl
```

一旦启动了 bash shell（或者执行一个 shell 脚本），就能创建在这个 shell 进程内可见的局部变量了。可以通过`=`给环境变量赋值，值可以是数值或字符串，如果要给变量赋一个含有空格的字符串值，必须用引号来界定字符串的首和尾。e.g.

```bash
[zhangzh@node01 sshpass-1.08]$ echo $my_var          # 为定义的变量会返回空值                                                                                                                               
                                                                
[zhangzh@node01 sshpass-1.08]$ my_var=hello
[zhangzh@node01 sshpass-1.08]$ echo $my_var
hello
[zhangzh@node01 sshpass-1.08]$ my_var=hello world    # 没有单引号的话，bash shell会以为下一个词是另一个要执行的命令
bash: world: 未找到命令...
[zhangzh@node01 sshpass-1.08]$ my_var="hello world"
[zhangzh@node01 sshpass-1.08]$ echo $my_var
hello world
[zhangzh@node01 sshpass-1.08]$ my_var='hello linux'  # 单双引号不做区别
[zhangzh@node01 sshpass-1.08]$ echo $my_var
hello linux
```

设置了局部环境变量后，就能在 shell 进程的任何地方使用它了。但是，如果生成了另外一个 shell，它在子 shell 中就不可用。e.g.

```bash
[zhangzh@node01 sshpass-1.08]$ my_var='hello linux'
[zhangzh@node01 sshpass-1.08]$ echo $my_var
hello linux
[zhangzh@node01 sshpass-1.08]$ bash    # 新建bash会话
[zhangzh@node01 sshpass-1.08]$ echo $my_var

[zhangzh@node01 sshpass-1.08]$
```

在子 shell 中无法使用用户定义变量`my_var`。通过命令`echo $my_var`所返回的空行就能够证明这一点。

当退出子 shell 并回到原来的 shell 时，这个局部环境变量依然可用，类似地，如果在子进程中设置了一个局部变量，那么一旦退出了子进程，那个局部环境变量就不可用。

<mark style="color:red;">**那么需要该变量在所有进程中都是可见的，就需要设置全局变量。**</mark>

#### **全局变量**

创建全局环境变量的方法是先创建一个局部环境变量，然后再把它导出到全局环境中，这个过程通过`export`命令来完成，**变量名前面不需要加**`$` 。

```bash
[zhangzh@node01 sshpass-1.08]$ echo $my_var
hello linux
[zhangzh@node01 sshpass-1.08]$ export my_var    # 变量名前面不需要加 $
[zhangzh@node01 sshpass-1.08]$ bash
[zhangzh@node01 sshpass-1.08]$ echo $my_var
hello linux
```

修改子 shell 中全局环境变量并不会影响到父 shell 中该变量的值，子 shell 甚至无法使用`export`命令改变父 shell 中全局环境变量的值，甚至子 shell 重新定义并导出了变量`my_var`，但父 shell 中的`my_var`变量依然保留着原先的值。

当然，既然可以创建新的环境变量，自然也能删除已经存在的环境变量。可以用`unset`命令完成这个操作。在`unset`命令中引用环境变量时，**记住不要使用**`$`

```bash
[zhangzh@node01 sshpass-1.08]$ echo $my_var
hello linux
[zhangzh@node01 sshpass-1.08]$ unset my_var
[zhangzh@node01 sshpass-1.08]$ echo $my_var

[zhangzh@node01 sshpass-1.08]$ 
```

{% hint style="success" %}
在涉及环境变量名时，什么时候该使用`$`，什么时候不该使用`$`，实在让人摸不着头脑。&#x20;

记住一点就行了：如果要用到变量，使用`$`；如果要操作变量，不使用`$`。

这条规则的一个例外就是使用`printenv`显示某个变量的值。
{% endhint %}

<mark style="color:red;background-color:red;">**如果子进程中删除了一个全局环境变量， 这只对子进程有效。该全局环境变量在父进程中依然可用。**</mark>

默认的环境变量有很多，在[这里](https://blog.csdn.net/Michael177/article/details/124639138)查看全部的默认变量，这里列出一些常用的环境变量名称：

<table><thead><tr><th width="228.36328125">常用环境变量</th><th>作用</th></tr></thead><tbody><tr><td><strong>PATH</strong></td><td><strong>决定了 shell 将到哪些目录中寻找命令或程序</strong></td></tr><tr><td>LIBRARY_PATH</td><td>用于在程序编译期间查找动态链接库时指定查找共享库的路径</td></tr><tr><td>LD_LIBRARY_PATH</td><td>用于在程序加载运行期间查找动态链接库时指定查找共享库的路径</td></tr><tr><td>INCLUDE</td><td>用于在程序编译期间查看头文件的路径</td></tr><tr><td>PBS_O_HOST</td><td>提交作业的主机名</td></tr><tr><td>PBS_O_WORKDIR</td><td>提交作业的工作路径</td></tr><tr><td>PBS_JOBID</td><td>作业被 PBS 系统指定的作业号</td></tr><tr><td>PBS_QUEUE</td><td>PBS 脚本在执行时的队列名</td></tr><tr><td>PBS_NODEFILE</td><td>PBS 系统指定的作业运行的节点名</td></tr></tbody></table>

在 shell 命令行界面中输入一个外部命令时，shell 必须搜索系统来找到对应的程序。`PATH`环境变量定义了用于进行命令和程序查找的目录。例如，输出中显示了有 8 个可供 shell 用来查找命令和程序。`PATH`中的目录使用冒号分隔。

```bash
[zhangzh@node01 ~]$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin: 10 /sbin:/bin:/usr/games:/usr/local/games
[zhangzh@node01 ~]$
```

如果命令或者程序的位置没有包括在`PATH`变量中，那么如果不使用绝对路径的话，shell 是没法找到的。如果 shell 找不到指定的命令或程序，它会产生一个错误信息（<mark style="color:green;">建议都使用绝对路径</mark>）：

```bash
[zhangzh@node01 ~]$ myprog
-bash: myprog: command not found $
```

登入 Linux 系统启动一个 bash shell 时，默认情况下 bash 会在几个文件中查找命令。这些文件叫作启动文件或环境文件。大多数 Linux 发行版只用这四个启动文件中的一到两个：

`$HOME/.bash_profile、$HOME/.bashrc、$HOME/.bash_login、$HOME/.profile`

这四个文件都以点号开头，这说明它们是隐藏文件（不会在通常的`ls`命令输出列表中出现）。它们位于用户的`HOME`目录下，所以每个用户都可以编辑这些文件并添加自己的环境变量，这些环境变量会在每次启动 bash shell 会话时生效。

当在登录时`echo`一些个性化的内容，如登录信息，应该将脚本添加在`$HOME/.bash_profile`中，而不得添加在`$HOME/.bashrc`中，因为在使用`sftp`等需要按行查看登录环境的命令时，`echo`会打乱其读取的内容，导致连接失败。

{% hint style="info" %}
**ls命令（list files）** 可以打印出当前工作目录下的所有文件（目录/地址也是一种文件）。

**echo命令** 用于在shell中打印shell变量的值，或者直接输出指定的字符串。
{% endhint %}

## 服务查询

`systemctl status` 是一个用于在 Linux 系统上查看服务状态的命令。它可以显示特定服务的详细信息，包括当前是否正在运行、最后一次启动时间、PID、主机名称等。e.g.

```shell
[zhangzh@node01 ~]# systemctl status firewalld.service 
?.firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enable>
   Active: active (running) since Mon 2022-04-18 10:56:12 CST; 1 weeks 0 days ago
     Docs: man:firewalld(1)
 Main PID: 3056 (firewalld)
    Tasks: 2 (limit: 1645568)
   Memory: 40.3M
   CGroup: /system.slice/firewalld.service
           ?..3056 /usr/libexec/platform-python -s /usr/sbin/firewalld --nofork --nopid
```

## 地址与端口

* **地址：**&#x5730;址通常指的是 IP 地址，它是用来唯一标识网络中的设备（例如计算机、路由器、服务器等）的，使得数据能够正确地发送和接收。IP 地址可以分为 IPv4 地址（如`192.168.1.1`）和 IPv6 地址（如`2001:0db8:85a3:0000:0000:8a2e:0370:7334`）。
* **端口：**&#x7AEF;口是一个用来标识应用程序或服务的逻辑通道。在网络通信中，数据包通过端口来确定应该传递给哪个应用程序或服务。端口号是一个 16 位的数字，范围从`0`到`65535`。其中，`0`到`1023`的端口号是被预留给一些知名的服务（例如 HTTP 服务的端口号是`80`，HTTPS 服务的端口号是`443`）。一般情况下，用户自定义的应用程序会使用大于`1023`的端口号。

因此，地址和端口在网络通信中起着非常重要的作用，地址用于标识设备，而端口则用于标识设备上的应用程序或服务。

```sh
$ ifconfig        # 查看本机IP
$ netstat -aptn   # 查看本机端口号
$ ping ip         # 查看地址是否联通
$ telnet ip post  # 含端口号查看地址
```

## 路径与文件

**路径**是文件（目录也是文件）在 Linux 系统中的唯一位置。Linux 中路径分为两种：

* **绝对路径 ：**&#x662F;完全限定名称从根目录 / 开始，指定到达唯一单个文件所需要遍历的每个子目录；
* **相对路径：** 仅指定从工作目录到达该文件所需的路径。

{% hint style="info" %}
**cd命令（change directory）**&#x547D;令用于改变当前工作目录的命令，切换到指定的路径，如`cd ~`意为切换到家目录，`cd .`切换至当前工作目录，`cd ..`切换至工作目录的上一级目录。
{% endhint %}

## 通配符与正则表达

在前面的介绍中，或多或少已经接触了一些通配符与正则表达，二者是 Linux 中最强大的工具，虽然规则很多，但是值得反复学习和使用，受益终身。

**通配符用于匹配文件名。**&#x6BD4;如`find,ls,cp,mv`等命令支持通配符查找文件名。

<table><thead><tr><th width="83.1875" align="center">符号</th><th>解释及示例</th></tr></thead><tbody><tr><td align="center">*</td><td>匹配任何字符。e.g. <code>rm *.txt</code>删除当前目录下的所有以<code>.txt</code>结尾的文件。</td></tr><tr><td align="center">?</td><td>匹配单个字符。e.g. <code>ls file?.txt</code> 将匹配 <code>file1.txt</code>、<code>file2.txt</code> 等文件。</td></tr><tr><td align="center">[-]</td><td>范围匹配。e.g. <code>rm [a-z].txt</code>删除当前目录下的包含小写字母的文件，举一反三，<code>[a-zA-Z0-9]</code>意为<mark style="color:orange;">匹配所有大小写字母和阿拉伯数字。</mark></td></tr><tr><td align="center">{,}</td><td>选项匹配。e.g. <code>touch {a..z}.txt</code>按字母顺序创建名为<code>a.txt</code>到<code>z.txt</code>，删除同理。<code>touch {a.txt,b.txt}</code>创建名为<code>a.txt</code>和<code>b.txt</code>的文件。<code>cp a{.c,.c.bak}</code>为<code>a.c</code>创建名为<code>a.c.bak</code>的备份文件。</td></tr><tr><td align="center">\</td><td>转义字符。<mark style="color:orange;">转为表达字符的原始含义用。</mark>e.g. <code>ls \*.txt</code> 将匹配以 <code>*.txt</code> 结尾的文件</td></tr><tr><td align="center">!</td><td>取反匹配。e.g. <code>[!abc]</code>表示不包含<code>abc</code>中的任何字母</td></tr><tr><td align="center">^</td><td>同上</td></tr></tbody></table>

<details>

<summary>e.g. <strong>通配符实例</strong></summary>

```bash
[zhangzh@node01 ~]$ touch lab{1..20}
[zhangzh@node01 ~]$ ll
total 4
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab1
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab10
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab11
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab12
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab13
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab14
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab15
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab16
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab17
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab18
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab19
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab2
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab20
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab3
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab4
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab5
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab6
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab7
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab8
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab9
drwx------ 2 zhangzh ybj 4096 May  7 18:16 linux
[zhangzh@node01 ~]$ rm -rf lab1?
[zhangzh@node01 ~]$ ll
total 4
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab1
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab2
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab20
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab3
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab4
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab5
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab6
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab7
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab8
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:43 lab9
drwx------ 2 zhangzh ybj 4096 May  7 18:16 linux
[zhangzh@node01 ~]$ rm -rf lab*
[zhangzh@node01 ~]$ ll
total 4
drwx------ 2 zhangzh ybj 4096 May  7 18:16 linux 18:16 linuxsh
[zhangzh@node01 ~]$ touch {laab,lab11}
[zhangzh@node01 ~]$ ll
total 4
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:47 laab
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:49 laab1
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:46 lab1
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:47 lab11
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:46 lab2
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:46 lab3
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:46 lab4
-rw-r--r-- 1 zhangzh ybj    0 May  8 13:46 lab5
drwx------ 2 zhangzh ybj 4096 May  7 18:16 linux
[zhangzh@node01 ~]$ ls l?b1
lab1
[zhangzh@node01 ~]$ ls l*b1
laab1  lab1
[zhangzh@node01 ~]$ ls l?b*
lab1  lab11  lab2  lab3  lab4  lab5
[zhangzh@node01 ~]$ ls lab*    # 取反查找
lab1  lab11  lab2  lab3  lab4  lab5
[zhangzh@node01 ~]$ ls lab[^1]
lab2  lab3  lab4  lab5
```

</details>

**正则表达式元字符有字符匹配、匹配次数、位置锚定、分组。主要是处理文本里的内容，用来匹配文本里的字符串**，针对文件内容的文本过滤工具里，大都用到正则表达式，如`grep, sed, awk, vim, less, nginx, varnish`等命令，均支持正则表达式。

<table data-full-width="false"><thead><tr><th width="97" align="center">符号</th><th>解释</th></tr></thead><tbody><tr><td align="center">.</td><td>匹配任意单个字符</td></tr><tr><td align="center">*</td><td>匹配 0 个或多个前面的字符</td></tr><tr><td align="center">+</td><td>匹配 1 个或多个前面的字符</td></tr><tr><td align="center">？</td><td>匹配 1 次或 0 次前面的字符</td></tr><tr><td align="center">()</td><td>分组过滤，被括起来的内容表示一个整体</td></tr><tr><td align="center">|</td><td>匹配多个模式中的一个</td></tr><tr><td align="center">^</td><td>匹配行的开头。<code>grep '^start' file.txt</code> 将匹配以 <code>start</code> 开头的行</td></tr><tr><td align="center">$</td><td>匹配行的结尾。<code>grep 'end$' file.txt</code> 将匹配以 <code>end</code> 结尾的行</td></tr><tr><td align="center">\b</td><td>匹配单词的边界。<code>grep '\bword\b' file.txt</code> 将匹配独立的单词 <code>word</code></td></tr><tr><td align="center">\d</td><td>匹配数字字符。<code>grep '\d+' file.txt</code> 将匹配一个或多个数字。</td></tr><tr><td align="center">\w</td><td>匹配字母数字字符。<code>grep '\w+' file.txt</code> 将匹配一个或多个字母数字字符</td></tr><tr><td align="center">\s</td><td>匹配空白字符。<code>grep 'line\s+' file.txt</code> 将匹配以 <code>line</code> 开头的行，并跟随一个或多个空白字符</td></tr><tr><td align="center">{n}</td><td>匹配前面的元素恰好 n 次。<code>grep 'a{3}' file.txt</code> 将匹配 <code>aaa</code></td></tr><tr><td align="center">{n,}</td><td>匹配前面的元素至少 n 次。<code>grep 'a{2,}' file.txt</code> 将匹配至少两个连续的 <code>a</code></td></tr><tr><td align="center">{n,m}</td><td>匹配前面的元素至少 n 次，但不超过 m 次。<code>grep 'a{2,4}' file.txt</code> 将匹配两个到四个连续的 <code>a</code></td></tr></tbody></table>

## 根目录结构

Linux 的根目录通常有这些文件构成，它们的作用分别是：

```shell
/bin       存放普通用户所使用的命令；以二进制（binary）存储
/boot      操作系统的启动文件；
/dev       系统可识别的设备目录；
/etc       服务配置文件，yum安装地址；
/home      普通账号的家目录；
/lib       存放库文件.os；
/media     软硬盘挂载点；            
/opt       安装大型软件；
/proc/sys  虚拟内存，正在运行的信息被映射至这两个目录；
/tmp       临时文件存放目录；
/var       日志目录
```

## 软件编译

**GNU**编译器

**GCC**（GNU Compiler Collection，GNU编译器套件）

* GNU 开发的编程语言编译器。它是一套以 GPL 及 LGPL 许可证所发行的自由软件，也是 GNU 计划的关键部分，亦是自由的类 Unix 及苹果电脑 macOS X 操作系统的标准编译器。GCC（特别是其中的C语言编译器）也常被认为是跨平台编译器的事实标准
* GCC 可处理 C、C++、Fortran、Pascal、Objective-C、Java 以及 Ada 等语言

从 github 中下载一个开源软件（或者库），通常需要“三连”安装（使用`cmake`或其他指定编译安装命令的除外）

```
[zhangzh@node01 ~]$ ./configure
[zhangzh@node01 ~]$ make
[zhangzh@node01 ~]$ make install 
```

此时该开源软件的会默认安装到`/usr/local/lib`和`/usr/local/include`中

如果想指定安装位置（比如库文件将要做到 docker 镜像中，或者加入到 git 仓库中，需要独立出来），可以通过一下方式指定：`make DESTDIR=/install/directory install`。

随后在`.bashrc`中指定环境变量地址即可。

**参考：**

* [一个简单的 **make & makefile** 教程](https://zhuanlan.zhihu.com/p/92010728)
* [让世界再多一份 **GNU m4** 教程](https://segmentfault.com/a/1190000004104696#)

## 添加媒体

Linux 中，“媒体”指的是存储介质，如光盘、USB 闪存驱动器、硬盘等，用于安装、存储和传输数据。媒体通常需要被挂载到系统中，以便用户访问和操作。步骤是（属于临时挂载）：

*1、*&#x63D2;入媒体（u盘）到计算机，通常它的硬件名称为:`sda1`，可以用`fdisk -l`来查看当前的硬件名称 &#x20;

*2、*&#x5728;`mnt`目录下先建立一个 usb 的目录，如`# mkdir /mnt/usb`

*3、*&#x6302;载媒体：`mount -t vfat /dev/sda1 /mnt/usb`

*4、*&#x5378;载媒体：`umount /mnt/usb`&#x20;

*5、*&#x5220;除 usb 目录：`rm -rf /mnt/usb`

非临时挂载需要在`vi /etc/fstab`中修改配置，配置在重启后才能生效。

当发现无法卸载某个媒体，尝试使用`fuser -km`关闭所有进程。

## 配置别名

**alias命令** 创建常用命令的快捷形式，二者输入效果等价。例如：`alias ll='ls -latr'` 创建了一个命令别名 `ll`等价于`ls -latr`，每次配置别名仅在当前 bash 中生效，把别名保存在 `~/.bashrc`中将全局生效，具体参考这篇[文章](http://superuser.com/a/183980/7106)。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://s-klnw.gitbook.io/study-manual/0.-linux-commands/1.1-xi-tong-guan-li-lei-ming-ling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
