# 进程 进程是一个在系统中运行的程序 进程是已启动的可执行程序的运行实例,进程有以下组成部分 * 已分配内存的地址空间 * 安全属性,包括所有权凭据和特权 * 进程代码的一个或多个执行线程 * 进程状态 程序:二进制文件,是静态的 `/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 ```