08-27-周三_17-09-29

This commit is contained in:
2025-08-27 17:10:05 +08:00
commit 86df397d8f
12735 changed files with 1145479 additions and 0 deletions

680
Linux基础/进程管理.md Normal file
View File

@@ -0,0 +1,680 @@
# 进程
进程是一个在系统中运行的程序
进程是已启动的可执行程序的运行实例,进程有以下组成部分
* 已分配内存的地址空间
* 安全属性,包括所有权凭据和特权
* 进程代码的一个或多个执行线程
* 进程状态
程序:二进制文件,是静态的
`/bin/date``/usr/sbin/httpd``/usr/sbin/sshd``/usr/local/nginx/sbin/ngix`
进程:是程序运行的过程,动态的,有生命周期及运行状态
# 进程类型
守护进程:在系统引导过程中启动的进程,跟终端无关的进程
前台进程:跟终端相关,通过终端启动的进程
# 进程的生命周期
![img](进程管理/01.进程生命周期.png)
父进程复制自己的地址空间(fork)创建一个新的(子)进程结构。每个新进程分配一个唯一的进程ID(PID)满足跟踪安全性之需。PID和父进程ID(PPID)是子进程环境的元素,任何进程都可以创建子进程,所有进程都是第一个系统进程的后代。
# systemd简介
首先 systmed 是一个用户空间的程序,属于应用程序,不属于 Linux 内核范畴。Systemd 是 Linux 系统中最新的初始化系统init它主要的设计目标是克服 sysvinit这个是centos6中的初始化系统固有的缺点提高系统的启动速度。
Linux内核加载启动后用户空间的第一个进程就是初始化进程这个程序的物理文件约定位于`/sbin/init`当然也可以通过传递内核参数来让内核启动指定的程序。这个进程的特点是进程号为1代表第一个运行的用户空间进程。不同发行版采用了不同的启动程序主要有以下几种主流选择
* 以 Ubuntu 为代表的 Linux 发行版采用 upstart
* 红帽系列发行版本中
- 红帽6以前的版本使用System V init
- 红帽7及以后使用systemd
RockyLinux上所有的进程都是systemd的后代systemd的功能繁多不仅用来管理服务还可以管理挂载点定义定时任务等。这些工作都是由编辑相应的配置单元文件完成的。
## systemd unit 类型
systemd需要管理的功能比较多所以支持的配置单元类型也比较繁多我们在日常使用Linux的过程中对系统服务的管理最多所以我们主要了解一下`service`类型即可,其他类型作为一个了解,下面列举出所有类型详细的解释。
| **单元类型** | **文件格式** | **描述** |
| :------------- | :----------- | :----------------------------------------------------------- |
| Service unit | .service | 服务类 |
| Target unit | .target | 一个 unit 服务组,用于模拟实现运行级别 |
| Automount unit | .automount | 文件系统自动挂载点 |
| Device unit | .device | 内核识别的设备文件 |
| Mount unit | .mount | 文件系统挂载点 |
| Path unit | .path | 文件或目录 |
| Scope unit | .scope | 外部创建的进程 |
| Slice unit | .slice | A group of hierarchically organized units that manage system processes. |
| Snapshot unit | .snapshot | 系统快照 |
| Socket unit | .socket | 套接字 |
| Swap unit | .swap | 标识 swap 设备 |
| Timer unit | .timer | systemd 的计时器 |
## unit 文件保存位置
我们目前了解到文件所在的位置即可,关于文件内部的格式与如何修改这些文件,我们会在后续的服务搭建过程中细讲。
| **目录** | **描述** |
| :----------------------- | :-------------------------------- |
| /usr/lib/systemd/system/ | RPM 包安装时分发的 unit 文件 |
| /run/systemd/system/ | systemd 运行时创建的文件 |
| /etc/systemd/system/ | systemctl enable 创建的 unit 文件 |
# 管理系统服务
systemd 的主要命令行工具是`systemctl`
```shell
systemctl [选项...] {命令} ...
```
## systemctl常用命令
这边列举出来的命令会在后面的学习过程中经常用到,所以大家只要对本部分中系统管理的命令合集有一个影响即可。
| **命令** | **描述** |
| :----------------------------------------------------------- | :------------------------------------- |
| systemctl start name.service | 启动服务 |
| systemctl stop name.service | 停止服务 |
| systemctl restart name.service | 重启服务(没启动的服务会启动) |
| systemctl try-restart name.service | 只重启正在运行的服务 |
| systemctl reload name.service | 重载配置文件 |
| systemctl status name.service systemctl is-active name.service | 检查服务状态检查服务是否启动 |
| systemctl list-units --type service --all | 显示所有的服务状态 |
| systemctl enable name.service | 启用开机自启服务 |
| systemctl disable name.service | 停用自启服务 |
| systemctl status name.service systemctl is-enabled name.service | 检查服务状态查看服务是否自启 |
| systemctl list-unit-files --type service | 查看所有服务 |
| systemctl list-dependencies --after | 列出在指定服务之前启动的服务(依赖) |
| systemctl list-dependencies --before | 列出在指定服务之后启动的服务(被依赖) |
# ps
ps命令用于显示当前进程的状态类似于 windows 的任务管理器
```shell
ps [选项]
```
## 选项
* **-a**:列出所有的进程
* **-e**:列出所有的进程,等同于`-A`
* **-f**:显示不包含资源使用率的相关信息
* **H**:以进程层级格式显示进程相关信息
* **-w**:显示加宽可以显示较多的信息
* **-u**:显示较详细的信息
* **-x**:显示其他使用者的进程
显示信息的格式说明
| **列名** | **说明** |
| :------- | :----------------- |
| USER | 进程拥有者 |
| PID | 进程ID |
| %CPU | 占用的 CPU 使用率 |
| %MEM | 占用的内存使用率 |
| VSZ | 占用的虚拟内存大小 |
| RSS | 占用的常驻内存大小 |
| TTY | 执行的终端编号 |
| STAT | 该进程的状态* |
| START | 进程开始时间 |
| TIME | CPU使用时间 |
| COMMAND | 所执行的命令 |
*STAT表示的进程状态有如下几种
* **D**: 无法中断的休眠状态 ,将一直等待事件的发生或等待某种系统资源
* **R**: 正在执行中
* **S**: 可中断状态
* **T**: 暂停执行
* **Z**: 不存在但暂时无法消除,也叫僵尸进程
* 每个进程在运行结束后都会处于僵死状态,等待父进程调用进而释放系统资源,处于该状态的进程已经运行结束,但是它的父进程还没有释放其系统资源
* 孤儿进程:
* **W**: 没有足够的内存可分配
* **<**: 高优先序的进程
* **N**: 低优先序的进程
* **+**:前台进程
* **l**:多线程进程
* **s**:主进程(先导进程)
## 实例
**常用组合ps aux**
```bash
u以用户为中心组织进程状态信息显示
a与终端相关的进程
x与终端无关的进程
[root@localhost ~]# ps aux | head -n 5
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 128144 6656 ? Ss 5月10 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S 5月10 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 5月10 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< 5月10 0:00 [kworker/0:0H]
```
**常用组合ps -aux**
```sh
-a: 列出所有的进程
-u: 显示较详细的信息
-x: 显示其他使用者的进程
[root@localhost ~]# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.9 172972 16128 ? Ss 20:38 0:01 /usr/lib/sys
root 2 0.0 0.0 0 0 ? S 20:38 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 20:38 0:00 [rcu_gp]
root 4 0.0 0.0 0 0 ? I< 20:38 0:00 [rcu_par_gp]
root 5 0.0 0.0 0 0 ? I< 20:38 0:00 [slub_flushw
root 6 0.0 0.0 0 0 ? I< 20:38 0:00 [netns]
```
**ps aux和ps -aux两个命令的区别**
`ps aux` 是一种 **BSD 风格**`ps` 命令,它不需要破折号(`-`)作为选项的前缀。
- **`a`**:显示所有用户的进程,包括其他用户的进程(不仅限于当前用户)。
- **`u`**以用户为中心的格式显示进程信息提供更多详细信息如用户名、CPU 和内存使用率等。
- **`x`**显示没有控制终端TTY的后台进程。
`ps -aux``ps aux` 看起来很相似,但它们有不同的含义。
- 这里的 `-` 表示使用的是 **UNIX 标准****POSIX 标准**`ps` 选项。
- 作为 POSIX 风格,`-a``-u``-x` 的含义会有所不同,甚至可能与 BSD 风格冲突。
**常用组合ps -ef**
```bash
-e显示所有进程
-f显示完整格式程序信息
[root@localhost ~]# ps -ef |head -n 10
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 5月10 ? 00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0 0 5月10 ? 00:00:00 [kthreadd]
root 3 2 0 5月10 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 5月10 ? 00:00:00 [kworker/0:0H]
root 6 2 0 5月10 ? 00:00:00 [kworker/u256:0]
root 7 2 0 5月10 ? 00:00:00 [migration/0]
root 8 2 0 5月10 ? 00:00:00 [rcu_bh]
root 9 2 0 5月10 ? 00:00:01 [rcu_sched]
root 10 2 0 5月10 ? 00:00:00 [lru-add-drain]
```
**常用组合ps -efH**
```shell
`查看进程以层级格式类似于pstree命令`
[root@localhost ~]# ps -efH
root 1 0 0 14:26 ? 00:00:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 479 1 0 14:26 ? 00:00:00 /usr/lib/systemd/systemd-journald
root 500 1 0 14:26 ? 00:00:00 /usr/sbin/lvmetad -f
root 507 1 0 14:26 ? 00:00:00 /usr/lib/systemd/systemd-udevd
root 615 1 0 14:27 ? 00:00:00 /sbin/auditd
polkitd 638 1 0 14:27 ? 00:00:00 /usr/lib/polkit-1/polkitd --no-debug
dbus 639 1 0 14:27 ? 00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root 646 1 0 14:27 ? 00:00:00 /usr/sbin/NetworkManager --no-daemon
root 649 1 0 14:27 ? 00:00:00 /usr/sbin/irqbalance --foreground
root 653 1 0 14:27 ? 00:00:00 /usr/lib/systemd/systemd-logind
root 655 1 0 14:27 ? 00:00:00 /usr/sbin/crond -n
chrony 661 1 0 14:27 ? 00:00:00 /usr/sbin/chronyd
root 662 1 0 14:27 ? 00:00:00 login -- root
```
**按照CPU使用率排序查看所有进程**
```shell
[root@localhost ~]# ps -aux --sort %cpu # 递增
[root@localhost ~]# ps -aux --sort -%cpu # 递减
```
**按照实际内存使用排序查看所有进程**
```shell
[root@localhost ~]# ps -aux --sort rss # 递增
[root@localhost ~]# ps -aux --sort -rss # 递减
```
**按照父子进程显示ssh服务的层级关系**
```shell
[root@localhost ~]# ps -auxf |grep sshd
# ps -efH
root       6814  0.0  0.2 112756  4320 ?        Ss   09:06   0:00 /usr/sbin/sshd -D
root       7097  0.0  0.2 158760  5576 ?        Ss   09:06   0:00  \_ sshd: root@pts/0
root       7337  0.1  0.2 158760  5588 ?        Ss   10:21   0:00  \_ sshd: root@pts/1
root       7364  0.0  0.0 112724   988 pts/1    S+   10:24   0:00          \_ grep --color=auto sshd
```
**自定义显示格式**
```shell
[root@localhost ~]# ps -axo user,pid,ppid,%mem,%cpu,command --sort -%cpu
```
**查看指定进程的PID多种查看的方式**
```shell
[root@localhost ~]# cat /run/sshd.pid 
[root@localhost ~]# ps -aux |grep sshd
[root@localhost ~]# pgrep -l sshd
[root@localhost ~]# pidof sshd
```
**查看进程树**
```shell
[root@localhost ~]# yum install -y psmisc
[root@localhost ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
├─agetty
├─atd
├─auditd─┬─sedispatch
│ └─2*[{auditd}]
├─bluetoothd
├─chronyd
├─crond
├─dbus-broker-lau───dbus-broker
├─firewalld───{firewalld}
├─irqbalance───{irqbalance}
├─lsmd
├─mcelog
├─polkitd───7*[{polkitd}]
├─rsyslogd───2*[{rsyslogd}]
├─sshd───sshd───sshd───bash───bash───pstree
├─systemd───(sd-pam)
├─systemd-journal
├─systemd-logind
├─systemd-udevd
└─tuned───3*[{tuned}]
```
# top
top命令用于实时显示 process 的动态
## 示例
```shell
[root@localhost ~]# top
```
第1行系统时间、运行时间、登录终端数、系统负载三个数值分别为1分钟、5分钟、15分钟内的平 均值,数值越小意味着负载越低)。
第2行进程总数、运行中的进程数、睡眠中的进程数、停止的进程数、僵死的进程数。
第3行用户占用资源百分比、系统内核占用资源百分比、改变过优先级的进程资源百分比、空闲的资源百分比等。
第4行物理内存总量、内存使用量、内存空闲量、作为内核缓存的内存量。buffer和cache之间的区 别cache是提高cpu和内存之间的数据交换速度buffer是io设备和存储设备之间的缓冲区
第5行虚拟内存总量、虚拟内存使用量、虚拟内存空闲量、已被提前加载的内存量。
## 选项
* **-d**: 改变显示的更新速度,或是在交互式指令列( interactive command)按 s
* **-c**: 切换显示模式,共有两种模式,一是只显示程序的名称,另一种是显示完整的路径与名称
* **-S**: 累积模式,会将己完成或消失的子行程 ( dead child process ) 的 CPU time 累积起来
* **-s**: 安全模式,将交互式指令取消, 避免潜在的危机
* **-i**: 不显示任何闲置 (idle) 或无用 (zombie) 的行程
* **-n**: 更新的次数,完成后将会退出 top
* **-b**: 显示模式,搭配 "n" 参数一起使用,可以用来将 top 的结果输出到文件内
* **-z**彩色
## 交互模式快捷键
| 快捷键 | 功能 |
| :----- | :------------------------------------------------------- |
| 空格 | 立即刷新 |
| P | 根据CPU使用多少排序 |
| T | 根据时间、累计排序 |
| q | 退出top命令 |
| m | 切换显示内存信息 |
| t | 切换显示进程和CPU状态信息 |
| c | 切换显示命令名称和完整命令行 |
| M | 根据内存的大小排序 |
| W | 将当前设置写入 ~/.toprc  文件中这是top配置文件推荐方法 |
| N | 以PID的大小排序 |
| z | 彩色 |
## 实例
* 显示进程信息每个1秒钟刷新一次
```shell
[root@localhost ~]# top -d 1
```
* 显示完整命令
```shell
[root@localhost ~]# top -c
```
* 更新两次后终止更新显示
```shell
[root@localhost ~]# top -n 2
```
* 显示指定的进程信息
```shell
[root@localhost ~]# top -p 7097
```
- 查看指定用户的进程
```sh
[root@localhost ~]# top -d 1 -u user01
```
- 将2次top信息写入到文件
```sh
[root@localhost ~]# top -d 1 -b -n 2 > top.txt
```
# kill
kill 命令用于删除执行中的程序或工作
kill 可将指定的信号送至程序。预设的信号为 SIGTERM(15),可将指定程序终止
```shell
kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>][程序]
```
## 选项
* **-l <信号编号>** 若不加<信号编号>选项,则 -l 参数会列出全部的信号名称
* **-s <信号名称或编号>**:指定要送出的信息
* **[程序]**[程序]可以是程序的PID或是PGID
使用 kill -l 命令列出所有可用信号,最常用的信号如下
| **编号** | **信号名** | **作用** |
| :------- | :--------- | :--------------- |
| 1 | SIGHUP | 重新加载配置 |
| 2 | SIGINT | 通过键盘 `ctrl+c` 打印捕获信息,程序继续运行 |
| 3 | SIGQUIT | 通过键盘 `ctrl+\` 打印捕获信息,程序优雅退出 |
| 9 | SIGKILL | 强制终止 |
| 15 | SIGTERM | 终止(正常结束) |
| 18 | SIGCONT | 继续 |
| 19 | SIGSTOP | 停止 |
| 20 | SIGTSTP | 暂停`ctrl z` |
## 实例
* 杀死所有的ping命令在linux命令中使用反引号`包含的命令会优先执行,并将执行的结果作为参数提供给命令。
```shell
[root@localhost ~]# kill `pgrep ping`
```
* 强制杀死进程
```shell
[root@localhost ~]# kill -9 `pgrep ping`
```
* 温柔的杀死进程
```bash
[root@localhost ~]# kill -15 `pgrep ping`
```
# pkill
pkill 用于杀死一个进程,与 kill 不同的是它会杀死指定名字的所有进程
```shell
pkill [选项] name
```
## 选项
* **name** 进程名
* **-u**:指定用户名
* **-t**:指定终端
## 实例
* 结束所有的sshd进程
```shell
[root@localhost ~]# pkill sshd
```
* 结束用户user1的所有进程
```shell
[root@localhost ~]# pkill -u user1
```
* 终止pts/2上所有进程
```shell
[root@localhost ~]# pkill -t pts/2
```
* 终止pts/2上所有进程并结束pts/2
```shell
[root@localhost ~]# pkill -9 -t pts/1
```
* 查看远程登录用户,并踢出用户
```shell
[root@localhost ~]# w
 15:02:26 up  5:21,  2 users,  load average: 0.05, 0.03, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     tty1                      14:41   20:34   0.02s  0.02s -bash
root     pts/0    192.168.175.1    14:42    2.00s  0.05s  0.01s w
user1    pts/1   192.168.175.1     14:40   20:34   0.02s  0.02s -bash
[root@localhost ~]# pkill -u user1
```
# 进程优先级 nice
## Linux进程调度及多任务
每个CPU(或CPU核心)在一个时间点上只能处理一个进程通过时间片技术Linux实际能够运行的进程 (和线程数)可以超出实际可用的CPU及核心数量。Linux内核进程调度程序将多个进程在CPU核心上快速切换从而给用户多个进程在同时运行的假象。并发
### 相对优先级
由于不是每个进程都与其他进程同样重要可告知进程调度程序为不同的进程使用不同的调度策略。常规系统上运行的大多数进程所使用的的调度策略为SCHED_OTHER(也称为SCHED_NORMAL),但还有其他 一些调度策略用于不同的目的。SCHED_OTHER调度策略运行的进程的相对优先级称为进程的nice值 可以有40种不同级别的nice值。
在Linux中决定一个进程的优先级的因素有两个一个是PR值一个是NICE值PR值是由系统内核动态调控。而NICE值由我们用户自己决定。不过PR值跟NICE值之间也是有一定的关联的。
**NICE值的范围**-20到19数值越小优先级越高
**PR值的范围**-99到39其中0-39是与**NICE值**有着一定的对应关系
进程默认启动时nice为0优先级为20
![img](进程管理/进程优先级.png)
nice值越高表示优先级越低例如19该进程容易将CPU使用量让给其他进程
nice值越低表示优先级越高例如-20该进程更倾向于不让出CPU
### 查看进程的nice级别
#### 使用ps查看
```bash
[root@localhost ~]# ps -axo pid,command,nice --sort=nice
[root@localhost ~]# ps -axo pid,command,nice,cls --sort=-nice
```
TS表示该进程使用的调度策略为SCHED_OTHER
#### 使用top查看
NI实际nice级别
PR将nice级别显示为映射到更大优先级队列-20映射到0+19映射到39
#### 启动具有不同nice级别的进程
启动进程的时候为进程指定nice值
启动进程时通常会继承父进程的nice级别默认为0
```sh
[root@localhost ~]# nice -n -20 vim
[root@localhost ~]# ps -axo command,pid,nice |grep vim
```
## PRI
在top命令中可以看到有PR这个数值PR 和 nice 值都会影响进程执行的优先级。PR 由 OS 内核动态调整用户不能调整PR 值越低,进程执行的优先级越高)。
nice值用户可以自己调整在用户调整了nice值后系统会通过如下公式来调整新的PR值从而确定这个进程在系统中的优先级
```shell
PR() = PR() + nice
```
PR值是OS动态调整的但是PR的最终值还是需要由OS分析决定的
#### 更改现有进程的nice级别
调整进程的优先级(Nice Level) -20高) - - - 0 - - - (19低)
- 使用shell更改nice级别
```bash
[root@localhost ~]# vim
[root@localhost ~]# ps -axo command,pid,nice |grep vim
vim 1855 0
grep --color=auto vim 1888 0
[root@localhost ~]# renice -20 1855
1855 (process ID) old priority 0, new priority -20
[root@localhost ~]# ps -axo command,pid,nice |grep vim
vim 1855 -20
grep --color=auto vim 1895 0
```
# jobs
jobs 命令可以用来查看当前终端放入后台的任务
```shell
jobs [-lnprs] [任务声明 ...]
```
## 将任务放入到后台
Linux 命令放入后台的方法有两种:
* 在命令后面加入`空格 &`。使用这种方法放入后台的命令,在后台处于执行状态
* 命令执行过裎中按 Ctrl+Z 快捷键,命令在后台处于暂停状态
### 实例
* 将任务放入后台,然后查看任务
* "+"号代表最近一个放入后台的工作,也是工作恢复时默认恢复的工作
* "-"号代表倒数第二个放入后台的工作
```shell
[root@localhost ~]# top &
[root@localhost ~]# vi &
[root@localhost ~]# ping baidu.com > /dev/null &
# 让ping运行但是不显示结果
[root@localhost ~]# jobs
[1]   已停止               top
[2]-  已停止               vi
[3]+  运行中               ping baidu.com > /dev/null &
```
## 将任务恢复到前台
fg 命令用于把后台工作恢复到前台执行
```shell
fg %工作号
```
注意,在使用此命令时,% 可以省略,但若将% 工作号全部省略,则此命令会将带有 + 号的工作恢复到前台。另外,使用此命令的过程中, % 可有可无。
### 实例
* 将top恢复到前台
* 命令虽然是对的但是top这种需要交互的任务是无法后台的所以也恢复不了
```shell
[root@localhost ~]# top &
[1] 20584
[root@localhost ~]# jobs
[1]+  已停止               top
[root@localhost ~]# fg 1
```
## 后台任务恢复到后台运行
前面讲过,使用`Ctrl+z`快捷键的方式,可以将前台工作放入后台,但是会处于暂停状态,可以使用bg命令
```shell
bg %工作号
```
这里的 % 同上,可以省略
### 实例
* 将ping命令暂停到后台然后恢复后台运行
```shell
[root@localhost ~]# ping baidu.com > /dev/null
^Z # 这边按下了Ctrl+z
[1]+  已停止               ping baidu.com > /dev/null
[root@localhost ~]# jobs
[1]+  已停止               ping baidu.com > /dev/null
[root@localhost ~]# bg %1
[1]+ ping baidu.com > /dev/null &
[root@localhost ~]# jobs
[1]+  运行中               ping baidu.com > /dev/null &
```
# nohup
虽然可以将程序放在后台运行,但是一旦关闭远程连接那么程序就会中断,如果我们想要将程序一直保持在后台运行,那么我们可以有如下三个选择:
* 把需要在后台执行的命令加入`/etc/rc.local`文件,让系统在启动时执行这个后台程序。这种方法的问题是,服务器是不能随便重启的,如果有临时后台任务,就不能执行了
* 使用系统定时任务,让系统在指定的时间执行某个后台命令。这样放入后台的命令与终端无关,是不依赖登录终端的
* 使用 nohup 命令
```shell
nohup 命令 &
```
注意,这里的`&`表示此命令会在终端后台工作;反之,如果没有`&`,则表示此命令会在终端前台工作。
## 实例
* 让一个任务后台运行
```shell
[root@localhost ~]# nohup ping baidu.com &
```
我们退出远程连接,然后重新登录回来,会看到`ping baidu.com`依旧在运行,查看`~/nohup.out`文件可以看到程序执行输出的内容
```shell
[root@localhost ~]# ps aux |grep ping
root       7157  0.0  0.0 149968  1988 ?        S    14:12   0:00 ping baidu.com
[root@localhost ~]# tail -f nohup.out
```