Linux运维之用户接口及进程管理

一、实验环境(rhel7.0版本)

主机环境:rhel7.0

各主机信息

主机名IP
server172.25.254.1

 

二、操作系统与用户接口

 

操作系统由三部分组成:

  1. 内核(用来管理硬件资源);
  2. 应用程序(用来管理软件资源);
  3. 库。

用户接口(其实就是应用程序)分为两类:

  1. GUI接口(图形桌面接口);
  2. CLI接口(命令行用户接口)

对于GUI:针对linux系统有三种(Gnome、KDE、Xface);针对windows系统(explore.exe)
对于CLI:针对linux系统有六种(sh、bash、csh、ksh、zsh、tcsh);针对windows系统(cmd应用程序)

 

三、什么是进程

 

在Linux系统当中:【触发任何一个事件时,系统都会将它定义称为一个进程,并且给予这个进程一个ID,称为PID,同时根据触发这个进程的用户和相关属性关系,给予这个PID一组有效的权限设置】

 

1、进程与程序

 

(1)什么是进程与程序

  • 程序:通常为二进制程序,放置在存储媒介中(如硬盘、光盘、软盘、磁带等)
  • 进程:程序被触发后,执行者的权限与属性、程序的代码与所需数据都会被加载到内存中,操作系统给予这个内存中的单元一个标识符(PID),可以说进程是一个正在运行中的进程。

 

(2)什么是父进程,什么是子进程

  • 当我们登录系统后,会获取一个bash的shell,然后我们用这个bash提供的接口去执行另一个命令,例如touch等,那些另外执行的命令也会被触发成为PID。那么后来执行命令所产生的PID就是【子进程】,而在我们原本的bash环境下,就称为【父进程】。
  • 很多人常常会发现:【噫,明明我将有问题的进程关闭了,怎么过一阵子它又自动产生了?而且新产生的那个进程的PID与原先的还不一样,这是怎么回事?】不要怀疑,如果不是crontab计划任务的影响,肯定是由一个父进程存在,所以你杀掉子进程后,父进程就会主动再生成一个。那怎么办?找出父进程,然后将它删除就可以。
  • 某个进程的父进程该如何判断?就通过PPID来判断即可。

【1】、范例一:请在目前的bash环境下,再触发一次bash,并用【ps  -l】这个命令查看进程相关的输出信息。

我们可以发现:第一个bash的PID与第二个bash的PPID都是5867,因为第二个是来自于第一个所产生的。

 

(3)fork  and  exec:程序调用的流程

Linux的程序调用通常称为fork-and-exec的流程。进程都会借由父进程以复制(fork)的方式产生一个一模一样的子进程,然后被复制出来的子进程再以exec的方式执行实际要执行的进程,最后就成为一个子进程。

 

(4)系统与网络服务

我们知道系统每分钟都会去扫描/etc/crontab以及相关的配置文件来执行计划任务吧?那这个计划任务是谁负责的呢?是由crond这个进程管理的。我们将它在后台启动并一直持续不断的运行,即常驻于内存当中的进程。而常驻于内存当中的进程,我们称之为:服务。

 

2、Linux的多人多任务环境

 

(1)多人环境

在Linux系统上面有多种不同的帐号,每个帐号都有特殊的权限,只有一个帐号具有至高无上的权力,那就是root(系统管理员)。每个人进入Linux环境设置都可以随着每个人的喜好来设置(~/.bashrc)。这是因为每个人登录后获取的shell的PID不同。

 

(2)多任务操作

目前的CPU频率可高达几个GHz,这代表每秒可以运行10^9这么多次命令。我们的Linux可以让CPU在各个任务间切换,也就是说每个任务都仅占去CPU的几个命令次数,所以每秒都能够在各个进程之间切换。

 

(3)多重登录环境的七个基本终端界面

在Linux当中,默认提供了六个命令行登录界面,以及一个图形界面,你可以使用【Alt】+【F1】...【F7】来切换不同的终端界面,而且每个终端界面的登录者还可以不同。当然,我们也可以减少启动的终端进程。

 

(4)特殊的进程管理操作

Linux几乎不会宕机,因为它可以在任何时候,将某个被困住的进程杀掉,然后再重新执行该进程而不用重新启动。

那么如果我在Linux下以命令行界面登录,在屏幕当中显示错误信息后就挂掉了,动都不能动,该如何是好?这个时候默认的七个终端界面就帮上忙了。你可以随意再按【Alt】+【F1】...【F7】来切换到其他终端界面,用ps  -aux找出刚刚的错误进程,然后给它kill一下,哈哈!回到刚刚的终端界面。嗯,又恢复正常。

 

(5)bash环境下的任务管理

我们登录bash之后,就获取了一个名为bash的PID,而在这个环境下面所执行的其他命令,就几乎都是所谓的子进程。那么,在单一bash界面下,我可不可以执行多个任务呢?当然可以,可以【同时】执行,举例来说,我可以这样做:

[root@server ~]# cp file1 file2 &

在这个命令中,重点在那个&的功能,它表示将file1这个文件复制为file2,且放置于后台中执行,也就是说执行这一个命令之后,在这一终端界面仍然可以做其他任务。而当这一命令【cp  file1  file2】执行完毕之后,系统将在你的终端界面显示完成的信息。

 

(6)多人多任务的系统资源分配问题考虑

  1. 多人多任务确实有很多好处,但其实也有管理上的难题,因为用户越来越多会导致你管理上的困扰。
  2. 另外,由于用户日渐增多,当用户达到一定的人数后,通常你的机器就需要升级了,因为CPU的计算能力与内存的大小可能就不够用了。

 

四、任务管理(job  control)

 

任务管理是用来bash环境下的,也就是说:【当我们登录系统获取bash  shell之后,在单一终端下同时执行多个任务的操作管理】。

 

1、什么是任务管理

 

执行任务管理的操作中,其实每个任务都是目前bash的子进程,即彼此之间是有相关性的,我们无法用任务管理的方式由tty1的环境去管理tty2的bash。

或许你会觉得很奇怪,既然我可以在六个终端登录,那何必要使用任务管理呢?不要忘记了,我们可以在/etc/security/limit.conf里面设置用户同时登录的连接数,在这样的情况下,某些用户可能仅能以一个连接来工作。

要执行bash的任务管理必须要注意到的限制是:

  1. 这些任务所触发的进程必须来自于你shell的子进程(只管理自己的bash)
  2. 前台:可以控制于执行命令的这个环境称为前台的任务
  3. 后台:可以自动执行的任务,你无法使用【Ctrl】+c终止它,比如vim,但是可以使用bg、fg调用此任务。
  4. 后台中【执行】的金册号嗯不能等待terminal或shell的输入。

 

2、job  control的管理

 

(1)直接将命令丢到后台中【执行】的&

 

【1】、范例一:将/etc整个备份成为/tmp/etc.tar.gz,且不想要等待

[root@server ~]# tar zcfp /tmp/etc.tar.gz /etc/ &
[1] 2252      <==[job number] PID
[root@server ~]# tar: Removing leading `/' from member names
#在中括号内的号码为任务号码,该号码与bash的控制有关。
#后续的2252则是这个任务在系统中的PID,值与后续出现的数据是tar执行的数据流,
#由于我们没有加上数据流重定向,所以影响界面,不过不会影响前台的操作。

按下[Enter]键会出现下面的提示字符
[1]+  Done                    tar zcfp /tmp/etc.tar.gz /etc/
#此提示表示任务已经完成,但是由于没有对数据流进行重定向的处理,所以会出现此错误,导致前台被影响。

 

【2】、范例一:将/etc整个备份成为/tmp/etc2.tar.gz,且不想要等待,并对数据流进行重定向的处理

 

(2)将【目前】的任务丢到后台中【暂停】:[Ctrl]+z

 

[root@server ~]# vim ~/.bashrc 
#在vim的命令模式下,按下[Ctrl]+z组合键
[1]+  Stopped                 vim ~/.bashrc
[root@server ~]#       <==顺利获取了前台的操控权
[root@server ~]# find / -print
...(输出省略)...
^Z      <==此时屏幕上会非常的忙碌,因为屏幕上会显示所有的文件名,请按下[Ctrl]+z暂停
[2]+  Stopped                 find / -print

在vim的命令模式下,按下[Ctrl]+z这两个键,屏幕上会出现[1],表示这是第一个任务,而那个  +  代表最近一个被丢到后台的任务,且是目前后台默认会被使用的那个任务(与fg这个命令有关),而那个Stopped则代表目前这个任务的状态。在默认的情况下,使用[Ctrl]+z丢到后台当中的任务都是【暂停】状态。

 

(3)查看目前的后台任务状态:jobs

 

jobs [-lrs]

选项与参数:
-l:除了列出 job number 与命令串之外,同时列出 PID 的号码
-r:仅列出正在后台 run 的任务
-s:仅列出正在后台当中暂停(stop)的任务

【1】、范例一:查看目前的bash当中,所有的任务,与对应的PID

【目前我有两个任务在后台当中,两个任务都是暂停的,而如果为我仅输入fg时,那么那个【2】会被拿到前台当中来处理】。

其实  +  代表最近被放到后台的任务号码,-  代表最近第二个被放置到后台当中的任务号码。而第三个以后的任务。就不会有  +、-符号存在了。

 

(4)将后台任务拿到前台来处理:fg

 

fg %jobnumber
选项与参数:
%jobnumber:jobnumber为任务号码(数字),注意,那个%是可有可无的。

范例一:先以 jobs 查看任务, 再将任务取出
[root@server ~]# jobs -l
[1]-  1596 Stopped                 vim ~/.bashrc
[2]+  1597 Stopped                 find / -print
[root@server ~]# fg   <==默认取出那个+的任务,亦即[2],立即按下[Ctrl]+z
[root@server ~]# fg %1   <==直接规定取出哪个任务号码,再按下[Ctrl]+z
[root@server ~]# jobs -l
[1]+  1596 Stopped                 vim ~/.bashrc
[2]-  1597 Stopped                 find / -print

如果输入【fg  -】则代表将-号的那个任务号码拿出来,上面就是[2]-那个任务号码。

 

(5)让任务在后台下的状态变成运行中:bg

 

范例一:一执行find / -perm /7000 > /tmp/text.txt后,立刻丢到后台去暂停
[root@server ~]# find / -perm /7000 > /tmp/text.txt
^Z   #此时,请立刻按下[ctrl]+z暂停
[3]+  Stopped                 find / -perm /7000 > /tmp/text.txt

范例二:让该任务在后台下执行,并且观察它
[root@server ~]# jobs ; bg %3 ; jobs
[1]-  Stopped                 vim ~/.bashrc
[2]   Stopped                 find / -print
[3]+  Stopped                 find / -perm /7000 > /tmp/text.txt
[3]+ find / -perm /7000 > /tmp/text.txt &
[1]+  Stopped                 vim ~/.bashrc
[2]   Stopped                 find / -print
[3]-  Running                 find / -perm /7000 > /tmp/text.txt &

从上面,我们可以看到[3]的状态栏,已经由Stopping变成了Running,命令行最后方多了一个 & 符号,代表该任务被启动到后台了。

 

(6)fg、bg注意的内容

 

1、vim只能使用fg命令,不可以使用bg命令,因为vim命令只能在前台运行。

2、gedit既可以在前台运行也可以在后台运行。使用gedit,在前台运行,按下Ctrl+z,将其打入后台,会显示已经停止,通过ps ax命令查看时显示的状态是僵尸状态;使用gedit,在前台运行,按下Ctrl+c,直接将该进程杀死,什么都不显示,通过ps ax命令查看时,没有该进程。使用gedit &,在后台运行。只要输入过命令gedit &,并且不关闭,那么下次输入命令gedit,也默认的是后台运行。

3、当fg和bg后面都不跟相应的jobnum时,会默认显示数字后面带+,其次是后面带-。当有多个时,执行完+,之后用过jobs命令查看,+,-号的位置会发生变化,但是数字不会发生变化。

 

(7)管理后台当中的任务:kill

 

kill -signal %jobnumber
kill -l
选项与参数:
-l:这个是 L 的小写,列出目前kill能够使用的信号(signal)有哪些?
signal:代表给予后面接的那个任务什么样的指示,用 man 7 signal 可知
  1:进程重新加载配置
  2:删除进程在内存中的数据,相当于[Ctrl]+c
  3:删除鼠标在内存中的数据
  9:强行结束某个进程(不可被阻塞)
  15:正常关闭进程(可能会被阻塞)



针对信号2:
示例:在一个终端上输入ps命令查看该bash的pid,然后输入abcdef但是不运行,在另外一个终端上输入kill -2 pid  会发现那个终端上相当于自动加了ctrl+c,即新开了一行

针对信号3:
示例:ctrl+\之后,鼠标不显示了,需要再手动一下鼠标才能显示出来(只在虚拟机的终端中生效。)

针对信号9:
示例:kill - 9 bash的pid  会成功(即强行结束了bash这个进程)

针对信号15:
示例:在一个终端上输入gedit &,然后输入ps命令查看gedit &的pid,在另外一个终端上输入kill -15 pid     显示关闭了那个终端上的gedit(没有被阻塞)
但是,在一个终端上输入ps命令查看该bash的pid,在另外一个终端上输入kill -15 pid   发现没有什么作用(被阻塞了)

 

范例一:找出目前bash环境下的后台任务,并将该任务【强制删除】
[root@server ~]# jobs 
[1]+  Stopped                 vim ~/.bashrc
[2]   Stopped                 find / -print
[root@server ~]# kill -9 %2

[2]-  Stopped                 find / -print
[root@server ~]# jobs 
[1]+  Stopped                 vim ~/.bashrc
[2]-  Killed                  find / -print
# 再过几秒你再执行 jobs 一次,就发现 2 号任务不见了,因为被删除了。



范例二:找出目前bash环境下的后台任务,并将该任务【正常终止】掉
[root@server ~]# kill -SIGTERM %1

[1]+  Stopped                 vim ~/.bashrc
# -SIGTERM 与 -15 是一样的,你可以使用 kill -l 来查看
# 不过在这个案例中,vim的任务无法被结束,因为它无法通过kill正常终止
  1. 特别留意一下:-9这个信号通常是在【强制删除一个不正常的任务】时所使用的,-15则是以正常步骤结束一个任务(15也是默认值),两者之间并不相同。
  2. 通常某些进程你真的不知道怎么通过正常手段去终止它时,这才用到 -9 的。
  3. kill后面接的数字默认会是PID,如果想要管理bash的任务,就要使用 %+数字 这种方式了,即%不可被省略。

 

3、脱机管理问题

 

我们在任务管理当中提到的【后台】指的是在终端模式下可以避免[Ctrl]+c中断的一个情景,你可以说那个是bash的后台,并不是放到系统的后台中。所以,任务管理的后台依旧与终端有关

在这样的情况下,如果你是以远程方式连接到你的Linux主机,并且将任务以&的方式放到后台中,请问,在任务尚未结束的情况下你脱机了,该任务还会继续执行吗?答案是【否】,不会继续执行,而会被中断。

那怎么办?处理方法有两种:

  1. 第一种方法:使用at命令来处理。因为at是将任务放置到系统后台而与终端无关
  2. 第二种方法:使用nohup命令,nohup可以在脱机或i注销系统后,还能够让任务继续执行

 

nohup [命令或参数]      <==在终端前台中任务
nohup [命令或参数] &    <==在终端后台中任务

#值的一提的是:nohup不支持bash内置的命令,因此你的命令必须是外部的命令才行

 

1、先编辑一个会【睡着120秒】的进程
[root@server ~]# vim sleep.sh
#!/bin/bash
/bin/sleep 120s
/bin/echo "I have slpet 120 seconds"


2、丢到后台中去执行,并且立刻注销登录
[root@server ~]# chmod a+x sleep.sh 
[root@server ~]# nohup /root/sleep.sh &
[1] 3045
[root@server ~]# nohup: ignoring input and appending output to ‘nohup.out’   #输入Enter键

[root@server ~]# exit

如果你再次登录时,再使用pstree去查看你的进程,会发现 sleep.sh还在执行中,并不会被中断。

由于我们的进程最后会输出一个信息(即使没有输出信息,也会被定向),但是nohup与中断无关,因此这个信息的输出会被定向到【~/.nohup.out】,所以在上述命令中,当你输入 nohup 后,才会出现那个提示信息。

程序执行完毕之后,查看nohup.out文件的内容,内容如下:

 

五、进程管理

 

1、查看进程

 

(1)ps:将某个时间点的进程运行情况取下来

 

【1】、图形化方式查看

方法1、Applications——System Tools——System Monitor进行查看
方法2、命令行方式:gnome-system-monitor

 

【2】、命令行查看进程

命令参数含义
ps  
ps-A查看所有进程,与-e具有同样的效果
ps-a 查看在当前环境中(现行终端机)运行的进程,不包含环境信息
ps显示进程用户信息
psa 查看在当前环境中(现行终端机)运行的进程,包含环境信息
psx列出系统中所有运行包含tty设备(字符设备)的进程
psf显示父子进程关系
ps显示进程的详细信息(系统的资源调用)

 

【3】、ps命令的常用组合

ps aux显示系统中所有进程并显示进程用户
ps ef  显示进程详细信息并显示进程父子关系
ps ax 显示系统中的所有进程

注意:通过pstree命令可以查看进程开启的目录数(可以看到所有进程的初始化进程是systemd)

 

【4】、一个虚拟机的某个终端的东西在另一个终端上面显示?

示例:在1号终端上输入date命令,然后输入date > dev/pts/1(将1号终端上的date命令的结果显示到2号终端上面,其中/dev/pts/1是通过ps命令查看的——查看的是该bash所对应的字符设备(TTY))

 

(2)仅查看自己的bash相关进程:ps -l

 

使用  ps  -l  仅会列出与你的操作环境(bash)有关的进程,即最上层的父进程是你自己的bash而没有扩展到systemd这个进程中。

  • F:代表这个进程标识,说明这个进程的权限,常见的号码有:
  1. 若为4——表示此进程的权限为root
  2. 若为1——表示此进程仅执行复制(fork)而没有时即执行(exec)
  • S:代表这个进程的状态,主要的状态有:
  1. R(Running)——该进程正在运行中
  2. S(Sleep)——该进程目前正在睡眠状态,但可以被唤醒
  3. D——不可被唤醒的睡眠状态,通畅这个进程可能在等待I/o的情况
  4. T(Stop)——停止状态,可能是在任务控制(后台赞同)或跟踪状态
  5. Z——僵尸状态,进程已经停止但无法被删除至内存外
  • UID/PID/PPID:代表【此进程被该UID所拥有/进程的PID号码/此进程的父进程的PID号码】
  • C:代表CPU使用率,单位为百分比
  • PRI/NI:Priority/Nice的缩写,代表此进程被 CPU 执行的优先级,数值越小,优先级越高
  • ADDR/SZ/WCHAN:都与内存有关,ADDR指出该进程在内存的哪个部分,如果是个running的进程,一般就会显示【-】;SZ代表这个进程用掉多少内存;WCHAN:表示目前进程是否运行,若为【-】表示正在运行中
  • TTY:登录者的终端位置,若为远程登录则使用动态终端接口名称(pts/n)
  • TIME:使用  CPU  的时间,注意,是此进程实际花费 CPU  运行的时间,而不是系统时间。
  • CMD:表示造成此进程的触发进程命令是什么。

因此上面命令执行的结果表示【bash的进程数与 UID 为0的用户,状态为睡眠状态,之所以睡眠,是因为它触发 ps (状态为run)。此进程的PID为 3759,优先执行顺序为80,执行bash所获取的终端接口为pts/0,运行的状态是等待(wait)】

 

(3)查看系统所有进程:ps  aux

 

在 ps aux  显示的项目中,各字段的意义为:

  • USER:该进程属于所属用户帐号
  • PID:该进程的进程ID
  • %CPU:该进程使用掉的 CPU  资源百分比
  • %MEM:该进程所占用的物理内存百分比
  • VSZ:该进程用掉的虚拟内存量(KB)
  • RSS:该进程占用的固定内存量(KB)
  • TTY:该进程是在哪个终端上面运行,若与终端无关则显示?(问号)。另外,tty1-tty6是本机上面的登录进程,若为pts/0等,则表示是由网络连接进入主机的进程。
  • STAT:该进程目前的状态,主要的状态有
  1. R(Running)——该进程正在运行中,或在运行队列中等待
  2. S(Sleep)——该进程目前正在睡眠状态,但可以被唤醒
  3. D——不可被唤醒的睡眠状态,通畅这个进程可能在等待I/o的情况
  4. T(Stop)——停止状态,可能是在任务控制(后台赞同)或跟踪状态
  5. Z——僵尸状态,进程已经停止但无法被删除至内存外
  6. X——杀掉的进程,不应该出现
  7. 状态后面接的各个字母的含义为:l——内存中有锁定空间;N——优先级低;<——优先级高;+——前台运行;s——顶级进程。
  • START:该进程被触发启动的时间
  • TIME:该进程实际使用CPU运行的时间
  • COMMAND:该进程的实际命令是什么

僵尸进程介绍:

造成僵尸进程的原因在于该进程应该已经执行完毕,或是应该要你终止了,但是该进程的父进程却无法完整地将该进程结束掉,而造成该进程一直存在内存当中。如果你发现在某个进程地 CMD 后面接上了<defunct>时,就代表该进程是僵尸进程。

系统不稳定地时候就容易造成所谓地僵尸进程,可能是因为程序写得不好,或是用户地操作习惯不良所造成地。

通常僵尸进程都已经无法管理,而直接交给systemd这个进程来负责,偏偏systemd是系统第一个执行地进程,它是所有进程地父进程。我们无法杀掉该进程的(杀掉它,系统就死掉了),所以,如果产生僵尸进程,而过一阵子还没有办法通过内核非正常性地特殊处理来将该进程删除时,那你只好通过 reboot 地方式来将该进程kill 掉。


【1】、显示内存中有锁定状态的范例:

gedit &     #表示gedit这个记事本在后台运行(状态会显示Sl--表示内存中有锁定空间)

 

(4)显示进程的指定信息

 

ps ax -o    xxx显示进程的指定信息
ps ax -o    %cpu 显示进程cpu使用率
ps ax -o    %mem  显示进程内存使用率
ps ax -o    group显示进程所属组
ps ax -o    ppid显示进程的ppid
ps ax -o    user 显示进程用户
ps ax -o    comm显示进程名称
ps ax -o    rgroup显示进程rgroup
ps ax -o    nice显示进程优先级
ps ax -o    pid显示进程pid
ps ax -o    pgid显示进程pgid
ps ax -o    etime显示进程etime值
ps ax -o    ruser显示进程ruser
ps ax -o    time显示进程time值
ps ax -o   tty显示进程tty
ps ax -o    vsz显示进程vsz
ps ax -o   stat显示进程stat
ps ax -o   rss显示进程rss
ps ax -o   start显示进程start
  


 

(5)进程排序

 

【1】、ps  ax  --sort=+%cpu/-%cpu  -o  %cpu  按照cpu的使用率进行排序(+表示从小到大排序,-表示从大到小排序)


 

【2】、ps ax --sort=+%mem/-%mem    按照内存的使用率进行排序(+表示从小到大排序,-表示从大到小排序)

 

【3】、示例:显示系统中cpu占用率前5的进程:

 

方法1:ps ax --sort=-%cpu -o %cpu | head -n 6 | tail -n 5


 

方法2:ps ax --sort=-%cpu -o %cpu | head -n 6 | grep -v %CPU

 

【4】示例:显示系统中内存使用率前5的进程:

 

方法1:ps ax --sort=-%mem -o %mem,pid,comm | head -n 6 | grep -v %MEM


 

方法2:ps ax --sort=-%mem -o %mem,pid,comm | head -n 6 | grep -v PID


 

方法3:ps ax --sort=-%mem -o %mem,pid,comm | head -n 6 | grep -v COMMAND


 

方法4:ps ax --sort=-%mem -o %mem,pid,comm | grep -v %MEM | head -n 5

 


注意:grep -v 后面是要区分大小写的;
grep的用法:grep 关键字,抓取出来的是一行一行的信息
其中grep表示抓取的意思,例如,cat /etc/passwd | grep root表示显示/etc/passwd文件中的含有root关键字的信息
那么-v表示反向抓取,即不含有关键字的信息


 

(6)top:动态查看进程的变化

 

top [-d 数字] 
top [-bnp]

选项与参数:
-d:后面可以接秒数,就是整个过程界面更新地秒数,默认是5秒
-b:以批量地方式执行 top,通常会搭配数据流重定向来将批量地结果输出为文件
-n:与-b搭配,意义是,需要执行几次top的输出结果
-p:指定某些个PID来执行查看监测

在top执行过程中可以使用地按键命令:
      h/?:显示在top当中可以输入地按键命令
      1:显示cpu每个核的负载(切换看的是cpu的变化)
      s:调整刷新频率
      c/P:根据cpu占有率进行排序
      m/M:根据内存占有率进行排序
      N:以PID来排序
      T:由该进程使用地 CPU 时间累积排序
      u:查看指定用户,进程输入用户名,即可查看该用户发起的所有进程
      k:后面跟要作用的进程pid,和发起的信号等级,对某一个进程进行操作
      r:给予某个PID重新制定一个nice值
      q:退出top地按键

 

【1】、范例一:查看 top 命令的输出结果

top主要分为两部分界面,上面的界面为整个系统的资源使用状态,基本上总共有六行,显示的恩内容依序为:

  • 第一行(top...):这一行显示的信息分别为:
  1. 目前的时间,即15:51:30 这个项目
  2. 开机到目前为止所经过的时间,即  up  6:32 这个项目
  3. 已经登录系统的用户人数,即2  users 这个项目
  4. 系统在1、5、15分钟的平均任务负载。即代表的是,1、5、15分钟,系统平均要负责运行几个进程(任务)的意思。数据越小代表系统越闲置,若高于1就要注意你的系统进程是否太过频繁了。
  • 第二行(Tasks...):显示的是目前进程的总量与个别仅处讷古在什么状态(running、sleeping、stopped、zombie)。需要注意的是,最后的zombie那个数值,如果不是0,赶紧好好看看到底那个process变成僵尸了吧。
  • 第三行(%Cpu...):显示的是CPU的整体负载。需要注意的是wa项目,那个项目代表的是I/O wait,通常你的系统会变慢都是I/O产生的问题比较大。
  • 第四行与第五行:表示目前的物理内存与虚拟内存(Mem/Swap)的使用情况。要注意的是swap的使用量要尽量少,如果swap被用得很多,表示系统的物理内存实在不足。
  • 这个是在top进程当中输入命令时,显示状态的地方。

至于top下半部分的画面,则是每个进程使用的资源情况:

  • PID:每个进程的ID
  • USER:该进程所属的用户
  • PR:Priority的简写,进程的优先执行顺序,越小则越早被执行
  • NI:Nice的简写,与Priority有关,越小则越早被执行
  • %CPU:CPU的使用率
  • %MEM:内存的使用率
  • TIME+:CPU使用时间的累加。

 

【2】、范例二:使用内存使用率排序

top默认使用CPU使用率(%CPU)作为排序的依据。

按下【M】,若要恢复则按下【P】即可。

 

【3】、范例三:修改进程刷新时间间隔:

在默认情况下,每次更新进程资源的时间为3秒

输入命令top,再输入s,接着输入刷新时间间隔,如图所示,输入5 ,然后回车,则表示修改成功。

 

【4】、范例四:杀死某一进程:

 输入命令top,再输入k,显示屏会提醒输入被执行进程的id,再输入9(代表强行关闭进程),回车,操作成功。

 

【5】、范例五:将top的信息执行2次,然后将结果输出到/tmp/top.txt

[root@server ~]# top -b -n 2 > /tmp/top.txt
#这样一来,就可以将 top 信息存到/tmp/top.txt文件中了

 

【6】、范例六:我们自己的bash  PID 可由$$变量获取,请使用 top 持续查看该PID

[root@server ~]# echo $$
3244      <==就是这个数字,它是我们bash的PID
[root@server ~]# top -p 3244

 

【7】、范例七:承上题,上面的 NI 值是0,想要改成 10的话?

在top界面,按下r,输入要修改的进程的pid,在输入NICE值即可

 

(7)pstree——用来找进程的相关性

 

pstree [-A|-U] [-pu]
选项与参数:
-A:各进程树之间的连接以ASCII字符来连接
-U:各进程数之间的连接以Unicode的字符来连接,在某些终端界面下可能会有错误
-p:并同时列出每个进程的PID
-u:并同时列出每个进程所属帐号名称

 

【1】、范例一:查看 pstree  -A  命令的结果

[root@server ~]# pstree -A
systemd-+-ModemManager---2*[{ModemManager}]          #这行是ModeManager与其子进程
        |-NetworkManager---2*[{NetworkManager}]      #前面有数字,代表子进程的数量
        |-2*[abrt-watch-log]
        |-abrtd
...(下面省略)...

 

【2】、范例二:承上题,同时显示 PID  与users

[root@server ~]# pstree -Aup
systemd(1)-+-ModemManager(493)-+-{ModemManager}(518)
           |                   `-{ModemManager}(542)
           |-NetworkManager(669)-+-{NetworkManager}(675)
           |                     `-{NetworkManager}(682)
           |-abrt-watch-log(478)
           |-abrt-watch-log(482)
           |-abrtd(477)
...(省略)...
           |-dbus-launch(741,gdm)
...(省略)...
#在括号()内的即是PID以及该进程的owner,一般来说,如果该进程的拥有者与父进程相同就不会列出
#但如果与父进程不一样,那就会列出该进程的拥有者,看上面的741就转成了 gdm

 

  • 所有进程都是依附在  systemd  这个进程下面的。而且这个进程的PID是一号,因为它是由Linux内核所主动调用的第一个进程,所以PID就是一号了。
  • 重启启动 systemd  就是 reboot。

 

2、进程的管理

 

到底有多少信号,可以使用“ kill  -l(小写的L)”或 “man  7  signal”来查询。主要信号的代号、名称及内容如下:

代号名称内容
1SIGHUP启动被终止的进程,可让PID重新读取自己的配置文件,类似重新启动
2SIGINT相当于用键盘输入[Ctrl]+c来中断一个进程的运行
9SIGKILL代表强制中断一个进程的运行,如果该进程执行到一半,那么尚未完成的部分可能会有【半成品】产生,类似 vim会有 .filename.swp 保留下来
15SIGTERM以正常的方式结束进程来终止该进程(可能被阻塞)
19SIGSTOP相当于用键盘输入[Ctrl]+z来暂停一个进程的运行

 

(1)kill  -signal  PID

再次强调的是:kill后面直接加数字与加上 %number 的情况是不同的。因为任务管理中有  1  号任务,但是 PID 1 号则是专指【systemd】这个进程。你怎么可以将 systemd 关闭呢?所以务必记得那个%是专门用来进行任务管理的。

 

【1】、案例一:以 ps 找出rsyslogd 这个进程的 PID 后,再使用 kill 传送信息,使得 rsyslogd 可以重新读取配置文件。

看到【Jun  8 17:23:34 server rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="475" x-info="http://www.rsyslog.com"] rsyslogd was HUPed】的字样,就表示在 8/6 重新启动(restart)过了。

 

(2)killall  -signal  命令名称

 

killall [-iIe] [command name]
选项与参数:
-i:interactive及互动的意思,若需要删除时,会提示字符给使用者
-I:命令名称(可能含参数),忽略大小写
-e:exact的意思,表示【后面接的 command file 要一致】,但整个完整的命令不能超过15个字符

 

【1】、给予 rsyslogd 这个命令启动的PID 一个SIGHUP的信号

如果用 ps aux 仔细看一下,若包含所有参数,则/usr/sbin/rsyslogd  -n 才是最完整的。

 

【2】、强制终止所有以 httpd 启动的进程

 

【3】、依次询问每个bash进程是否需要被终止运行

若不加 -i 参数,所有的bash都会被root给杀掉,包括root自己的bash

 

要删除某个服务,最简单的方法就是利用killall,因为它可以将系统当中所有以某个命令名称启动的进程全部删除

 

(3)pkill  -u  用户名 -signal

 

pkill -u student(用户)-信号等级    #结束某个用户的进程  

  

 

3、关于进程的执行顺序

 

(1)Priority 与 Nice值

 

         PRI值越小,代表优先级越高。不过这个 PRI 值是由内核动态调整的,用户无法直接调整  PRI  值。先看看PRI在哪里出现

        由于PRI是内核动态年调整的,我们用户无权去干涉 PRI。如果要调整进程的优先级,就要通过nice值了,nice值就是上表的NI。一般来说,PRI  与  NI  的相关性如下:

PRI(new) = PRI(old) + nice

 

需要注意的两点:

  • 如果原本的 PRI  是50,并不是我们给予一个 nice=5,就会让 PRI 变成55。因为 PRI  是系统【动态】决定的,所以,虽然 nice 值可以影响 PRI,但最终的  PRI 仍要经过系统分析后才会决定。
  • 另外,nice 值是有正负的,而既然 PRI 越小则越早被执行,所以,当 nice 值为负值时,那么该进程就会降低 PRI 值,即变得较优先被处理。此外,你必须要留意到:
  1. nice值可调整的范围为 -20~19;
  2. root可随意调整自己或他人进程的 nice 值,且范围为 -20~19;
  3. 一般用户仅可调整自己进程的 nice 值,且范围仅为 0~19(避免一般用户抢占系统资源);
  4. 一般用户仅可将 nice值越调越高,例如本来 nice 为5,则未来仅能调整到大于5。

 

(2)调整 nice 值的两种方式

 

调整 nice 值的方式有两种:

  1. 一开始执行进程就立即给予一个特定的 nice 值:用 nice 命令;
  2. 调整某个已经存在的 PID 的 nice 值:用 renice 命令/在top命令界面用 r 来修改。

 

(3)nice:新执行的命令即给予新的nice值

 

nice [-n 数字] command
选项与参数:
-n:后面接一个数值,数值的范围 -20~19

 

【1】、范例一:用 root 给一个 nice 值为 -5,用于执行  vim,并查看进程

[root@server ~]# nice -n -5 vim &
[1] 2628
[root@server ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  1471  1467  0  80   0 - 29069 wait   pts/0    00:00:00 bash
4 T     0  2628  1471  0  75  -5 - 37318 signal pts/0    00:00:00 vim
0 R     0  2629  1471  0  80   0 - 30315 -      pts/0    00:00:00 ps

[1]+  Stopped                 nice -n -5 vim
[root@server ~]# ps ax -o pid,nice,comm,stat | grep 2628   # -o 用来查看指定的信息
 2628  -5 vim             T<
[root@server ~]# kill -9 %1

[1]+  Stopped                 nice -n -5 vim


#原本的 bash PRI 为80,所以 vim 默认应为 80,不过由于给予 nice 为 -5,因此 vim 的 PRI 降低了,PRI 与 NI 各减5。但不一定每次都是正好相同,因为内核会动态调整。

 

通常什么时候要将 nice 值调大?举例来说,一般是系统的后台任务中,某些比较不重要的进程的运行:例如备份任务。由于备份任务相当地消耗系统资源,这个时候就可以将备份命令的 nice 值调大一些,可以使系统地资源分配得更为公平。

 

(4)renice:已存在进程的 nice 重新调整

 

renice [number] PID
选项与参数:
PID:某个进程地 ID

 

【1】、范例一:找出自己的 bash PID,并将该 PID 的 nice 调整到 -5

从上面的范例中,我们也可以看出,虽然修改的是 bash 那个进程,但是该进程所触发的 ps 命令当中的 nice 也会继承为 -5 。整个 nice 值可以在父进程——>子进程之间进行传递。

 

4、查看系统资源信息

 

(1)free:查看内存使用情况

 

查看博客:https://mp.csdn.net/postedit/89321583

 

(2)uname:查看系统与内核相关信息

 

uname [-asrmpi]

选项与参数:
-a:所有系统相关信息,包括下面的数据都会被列出来
-s:系统内核名称
-n:节点名称
-r:系统内核发行版号
-v:系统内核版本
-m:本系统的硬件架构,例如 i686 或 x86-64等 
-p:CPU的类型,与 -m 类似,只是显示的是 CPU 的类型
-i:硬件的平台(x86)
-o:操作系统

 

上面示例中,各字段的含义:

  • 系统内核名成:Linux
  • 节点名称:foundation83.ilt.example.com
  • 系统内核发行版号:3.10.0-514.el7.x86_64
  • 系统内核版本:#1 SMP Wed Oct 19 11:24:13 EDT 2016
  • 本系统的硬件架构:x86_64
  • CPU的类型:x86_64
  • 硬件平台:x86_64
  • 操作系统:GNU/Linux

 

(3)uptime:查看系统启动时间与任务负载

 

  1. 当前时间:11:58:08
  2. 系统已运行的时间:1:22
  3. 当前在线用户 2 users
  4. 平均负载:0.00,0.01,0.05,最近1分钟、5分钟、15分钟系统的负载

 

(4)netstat:追踪网络或 socket 文件

 

查看博客:https://mp.csdn.net/postedit/83754957

 

(5)dmesg:分析内核产生的信息

 

不管是启动的时候还是系统运行过程中,只要是内核产生的信息,都会被记录到内存的某个保护区域中。demsg 这个命令就能够将该区域的信息读出来。

 

【1】、范例一:输出所有的内核启动时的信息

 

【2】、范例二:查找启动时,硬盘的相关信息是什么?

 

(6)vmstat:监测系统资源变化

 

如果改天你的服务器非常忙碌时,记得使用 vmstat 去看看,到底是哪个部分的资源被使用的最为频繁。一般来说,如果I/O部分很忙碌的换,你的系统会变得非常慢。

 

vmstat [-a] [延迟 [总计监测次数]]      <==CPU/内存等信息
vmstat [-fs]              <==内存相关
vmstat [-S 单位]          <==设置显示数据的单位
vmstat [-d]             <==与磁盘有关
vmstat [-p 分区]        <==与磁盘有关

选项与参数:
-a:使用inactive/active(活动与否)替换 buffer/cache 的内存输出信息
-f:开机到目前为止,系统复制(fork)的进程数
-s:将一些时间(启动到目前为止)导致的内存变化情况列表说明
-S:后面可以接单位,让显示的数据有单位,例如K/M替换Bytes的容量
-d:列出磁盘的读写容量统计表
-p:后面列出分区,可显示该分五的读写容量统计表

 

【1】、范例一:统计目前 CPU状态,每秒一次,共三次

  • 进程字段(procs)的项目分别为:
  1. r:等待运行中的进程数量;
  2. d:不可被唤醒的进程数量
  • 内存字段(memory)的项目分别为:
  1. swpd:虚拟内存被使用的容量
  2. free:未被使用的内存容量
  3. buff:用于换重存储器
  4. cache:用于高速缓存
  • 内存交换分区(swap)的项目分别为:
  1. si:由磁盘中将进程取出的容量
  2. so:由于内存不足而将没用到的进程写入到磁盘的swap的容量
  • 磁盘读写(io)的项目分别为:
  1. bi:由磁盘读入的区块数量
  2. bo:写入到磁盘中的区块数量
  • 系统(system)的项目分别为:
  1. in:每秒钟被中断的进程次数
  2. cs:每秒执行的事件切换次数
  • CPU的项目分别为:
  1. us:非内核层的CPU使用状态
  2. sy:内核层的CPU使用状态
  3. id:闲置的状态
  4. wa:等待I/O所消耗的 CPU 状态
  5. st:被虚拟机所使用的 CPU 状态(2.6.11以后才支持)

 

【2】、系统上面所有的磁盘的读写状态

 

六、特殊文件与进程

 

1、具有 SUID/SGID 权限的命令执行状态

 

我们可以看到 passwd 命令对应的二进制文件 /usr/bin/passwd 具有 SUID 的权限。那你可能会有疑问,为什么普通用户执行了 passwd 后,你就具有了 root 的权限爱你呢?不都是一般用户执行的吗?这时因为你在触发 passwd 后,会获得一个新的进程与 PID,该 PID 产生时通过 SUID 来给予该 PID 特殊的权限设置。

下面,我们使用 student 登录系统且执行 passwd 后,通过任务管理来解释一下:

[student@server ~]$ passwd
Changing password for user student.
Changing password for student.
(current) UNIX password:    <==这里按下[Ctrl]+d

[1]+  Stopped                 passwd
[student@server ~]$ pstree -uA
systemd-+-ModemManager---2*[{ModemManager}]
...(中间省略)...
        |-sshd---sshd---bash---su---bash(student)-+-passwd(root)   <==这这里我们会发现passwd这个进程的拥有者是root,而非student
        |                                         `-pstree
...(下面省略)...

 

2、/proc/* 代表的意义

 

[root@server ~]# ll /proc/
total 0
dr-xr-xr-x.  8 root           root                         0 Jun  9 10:35 1
dr-xr-xr-x.  8 root           root                         0 Jun  9 10:35 10
...(中间省略)...
-r--r--r--.  1 root           root                         0 Jun  9 16:50 vmstat
-r--r--r--.  1 root           root                         0 Jun  9 16:50 zoneinfo

基本上,目前主机上面的各个进程的 PID 都以目录的形式存在于 /proc 当中。举例来说,我们启动所执行的第一个程序 systemd 的 PID 是1,这个 PID 的所有相关信息都写入到 /proc/1/* 当中。我们直接查看 PID 为 1 的数据好了,它有点像这样:

[root@server ~]# ll /proc/1
total 0
dr-xr-xr-x. 2 root root 0 Jun  9 16:37 attr
-rw-r--r--. 1 root root 0 Jun  9 16:38 autogroup
-r--------. 1 root root 0 Jun  9 16:38 auxv
-r--r--r--. 1 root root 0 Jun  9 10:35 cgroup
--w-------. 1 root root 0 Jun  9 16:38 clear_refs
-r--r--r--. 1 root root 0 Jun  9 10:35 cmdline   <==就是命令串
-rw-r--r--. 1 root root 0 Jun  9 10:35 comm
-rw-r--r--. 1 root root 0 Jun  9 16:38 coredump_filter
-r--r--r--. 1 root root 0 Jun  9 16:38 cpuset
lrwxrwxrwx. 1 root root 0 Jun  9 16:38 cwd -> /
-r--------. 1 root root 0 Jun  9 10:35 environ   <==一些环境变量

如果你查看一下 cmdline 的话,你会发现:

 

文件名文件内容
/proc/cmdline加载内核时所执行的相关命令与参数,查看此文件,可了解命令是如何启动的
/proc/cpuinfo本机的 CPU 的相关信息,包含频率、类型与功能等
/proc/devices这个文件记录了系统各个主要设备的主要设备代号,与 mknod 有关
/proc/filesystem目前系统已经加载的文件系统
/proc/interrupts目前系统上面的 IRQ分配地址
/proc/ioports目前系统上面各个设备所配置的 I/O 地址
 /proc/kcore这个就是内存的大小。好大,对吧,但是不要读它
/proc/loadavg还记得 top 以及 uptime 吧?没错,上面的三个平津之就是记录在此
/proc/meminfo使用 free 列出的内存信息,在这里也能够查看到
/proc/modules目前我们的 Linux 已经加载的模块列表,也可以想成是驱动程序
/proc/mounts系统已经挂载的数据,就是用 mount 这个命令调用出来的数据
/proc/swaps到底系统挂载入的内存在哪里?使用的硬盘分区就记录在此
/proc/partitions使用 fdisk -l 会出现目前所由的硬盘分区吧?在这个文件当中也有记录
/proc/uptime就是用 uptime 的时候,会出现的信息
/proc/version内核的版本,就是 uname -a 显示的内容
/proc/bus/*一些总线的设备,还有 USB 的设备也记录在此

 

3、查询已使用文件或已执行进程使用的文件

 

(1)fuser:借由文件(或文件系统)找出正在使用该文件的进程

 

fuser [-umv] [-k] [-i] [-signal] file/dir
选项与参数:
-u:除了进程的 PID 之外,同时列出该进程的拥有者
-m:后面接的那个文件名会主动地上提到这个文件系统地最顶层,对 umount 不成功很有效
-v:可以列出每个文件与进程还有命令地完整相关性
-k:找出使用该文件/目录地 PID,并尝试以 SIGKILL 这个信号给予该 PID
-i:必须与 -k 配合,在删除 PID 之前会先询问使用者意愿
-signal:例如 -1、-15等,若不加的话,默认是 SIGKILL(-9)

 

【1】、范例一:找出目前所在目录的使用 PID / 所属帐号/ 权限是什么?

比较有趣的是,那个 ACCESS 的项目,那个项目代表的意义是:

  • c:此进程在当前的目录下(非子目录)
  • e:可被触发为执行状态
  • f:是一个被开启的文件
  • r:代表顶层目录(root  directory)
  • F:该文件被使用了,不过在等待响应中
  • m:可能为共享的动态函数库。

 

【2】、找出所有使用到 /proc 这个文件系统的进程

 

【3】、找到所有使用到 /home 这个文件系统的进程

[root@server ~]# echo $$
6733
[root@server ~]# cd /home/
[root@server ~]# fuser -muv .
                     USER        PID ACCESS COMMAND
/home:               root     kernel mount (root)/home
                     root       1499 ..c.. (root)bash   <==果然,自己的PID在
                     root       6733 ..c.. (root)bash
[root@server home]# cd 
[root@server ~]# umount /home/
umount: /home: target is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
#从fuser的结果可以知道,总共有2个进程在该目录下运行,那即使root离开了 /home,
#当然还是无法 umount 的。那要怎么办?哈哈,可以通过如下方法一一删除
[root@server ~]# fuser -mki /home/
/home:                1499c    <==你会发现,PID 跟上面查到的相同
Kill process 1499 ? (y/N)   <==这里会问你要不要删除,当然不要乱删除,通通取消

 

(2)lsof:列出被进程所使用的文件名称

 

相对于 fuser 是由文件或设备 找出使用该文件或设备的进程,反过来说,如何查出某个进程开启或使用的文件与设备呢?那就是 lsof

 

lsof [-aUu] [+d]
选项与参数:
-a:多项数据需要【同时成立】才显示出结果时
-U:仅列出 UNIX-like 系统的 socket 文件类型。
-u:后面接 username,列出该使用者相关进程所使用的文件
+d:后面接目录,亦即找出某个目录下面已经被使用的文件

 

【1】、列出目前系统上面所由已经被开启的文件与设备

[root@server ~]# lsof
[root@server ~]# lsof | more
COMMAND    PID  TID           USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
systemd      1                root  cwd       DIR              253,3      4096        128 /
systemd      1                root  rtd       DIR              253,3      4096        128 /
systemd      1                root  txt       REG              253,3   1214424   17297808 /usr
...(下面省略)
#注意到了吗?是的,在默认的情况下,lsof 会将目前系统上面已经打开的文件全部列出来
#所以,结果多的吓人。您可以注意到,第一个文件 systemd 执行的地方就在根目录
#而根目录,嘿嘿,所在的 inode 也显示出来了

 

【2】、仅列出关于 root 的所有进程所使用的 socket 文件

[root@server ~]# lsof -u root -a -U 
COMMAND    PID USER   FD   TYPE             DEVICE SIZE/OFF  NODE NAME
systemd      1 root    3u  unix 0xffff8800367cb680      0t0 11663 socket
...(下面省略)...
#注意到那个 -a 了吧,如果你分别输入lsof -u root 及 lsod -U,会有啥信息?
#使用 lsof -u root -U 及lsof -u root -a -U ,呵呵,都不同。-a 的用途就是使两个参数同属成立

 

【3】、请列出目前系统上面所有的被使用的外接设备

[root@server ~]# lsof +d /dev/ 
COMMAND    PID           USER   FD   TYPE             DEVICE SIZE/OFF  NODE NAME
systemd      1           root    0u   CHR                1,3      0t0  4483 /dev/null
#看吧,因为设备都在 /dev 里面嘛,所以,使用查找目录即可

 

【4】、显示属于 root 的 bash 这个程序所开启的文件

[root@server ~]# lsof -u root | grep bash 
ksmtuned   547 root  txt       REG              253,3    960368   16853911 /usr/bin/bash
bash      1499 root  cwd       DIR             253,21         6        128 /home
bash      1499 root  rtd       DIR              253,3      4096        128 /
...(下面省略)...

 

(3)pidof:找出正在执行的进程的PID

 

pidof [-sx] program_name
选项与参数:
-s:仅列出一个 PID 而不列出所有的 PID
-x:同时列出该 program_name 可能的 PPID 那个进程的 PID

 

【1】、范例一:列出目前系统上面 systemd 以及 rsyslogd 这两个程序的 PID

[root@server ~]# pidof systemd rsyslogd
1 478
# 1 478 分别是 systemd 及 rsyslogd 这两个程序的 PID
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值