2023年7月26日发(作者:)
张勤
1.1 Linux进程管理
Linux系统中几乎任何操作都会以进程的形式进行,比如浏览网页浏览器就作为进程运行,使用命令每个命令都会命令就会作为进程运行。Linux是一个多进程操作系统,每个程序启动时,可以创建一个或几个进程,与其他程序创建的进程共同运行在Linux内核空间中。每个进程都是一个独立的任务,进程依照操作系统内核制定的规则,轮换着被CPU执行。每个单独的进程运行在自己的虚拟地址空间中,并且只能通过安全的内核管理机制与其他进程交互。
在进程的生存期内,将使用许多系统资源。进程使用系统CPU运行自己的指令,并使用系统的物理内存保存自己的的数据;进程打开和使用文件系统中的文件,并直接或间接地使用系统中的物理设备。Linux必须跟踪进程本身及其拥有的系统资源,来保证能公平地管理该进程和系统中其他的进程。Linux系统与其他操作系统不同,进程创建和命令执行是二个不同的概念。虽然一般创建一个新的进程是为了运行一个指定的命令,但是不运行新命令也可以创建进程,不创建新进程也可以运行新命令。
当进程在运行时总是会处于以下5种状态中的一种,进程的状态决定了进程如何以及何时有权访问CPU。
(1) 可运行,处于该状态的进程,一旦有机会就会访问CPU。系统中一般会有多个进程处理这样的状态,但是由于在同一时间内只有一个进程可以在CPU中运行,所以实际上这些进程中只有一个在运行。然而由于可运行的进程进出CPU切换速度非常快,所以看上去好像有很多进程在同时运行。
(2) 自愿(可中断)休眠,当一个进程在没有可处理的内容时,则会进程该状态。一旦该进程有需要处理的内容时,会切换到可运行的状态。
(3) 非自愿(不可中断)休眠,在一些时候多个进程试图同时该某一个资源,而这个资源又不允许同时访问时,内核会将这多个进程只保留一个运行,其他进程会强制进入非自愿(不可中断)休眠状态,直到内核唤醒后就切换到可运行状态。
(4) 挂起的进程,用户可以通过“Ctrl+Z”将进程挂起,被挂起的进程在用户唤醒前不会执行任何操作。
(5) 僵尸进程,每个即将终止的进程会经历一个短暂的僵尸状态,然而有时有些进程会一直停留在僵尸状态。僵尸进程已经结束了执行,并且已经释放了几乎所有资源。
Linux除了用内核自身管理这些进程调度以外,还将这些信息通过工具程序传递给用户,并通过工具程序接受用户对某个进程的处理。
1.1.1 Linux进程查看
free:查看内存状态
free命令用于查看内存状态,该命令语法如下。
free [-b|-k|-m|-g] [-to] [-s <间隔秒数>]
1 / 16
张勤
常用选项:
-b:使用free命令时,显示的单位是Kbytes,可以使用-b(bytes)、-k(KB)、-m(MB)、-g(GB)改变显示单位。
-t:显示内存的总和行。
-o:不显示缓存区调节行。
-s <间隔秒数>:持续观察内存使用情况。比如间隔秒数指定为5,free命令每5秒查看内存状态一次。
free命令会显示内存的使用情况,包括物理内存、虚拟的交换文件内存、共享内存区段、以及系统核心使用的缓冲区等等。下面看几个free命令的例子。
以MB为单位显示内存使用情况。
[root@srv ~]# free -m
total used free shared buffers cached
Mem: 503 486 17 0 27 331
-/+ buffers/cache: 126 376
Swap: 1027 0 1027
每4秒查看内存状态一次,使用“Ctrl+C”停止查看。
[root@srv ~]# free -s 4
total used free shared buffers cached
Mem: 515340 497892 17448 0 28044 339820
-/+ buffers/cache: 130028 385312
Swap: 1052216 0 1052216
#4秒后又自动查看一次。
total used free shared buffers cached
Mem: 515340 498016 17324 0 28052 339820
-/+ buffers/cache: 130144 385196
Swap: 1052216 0 1052216
ps:查看进程
ps命令用于查看进程,该命令的选项非常多。下面分类介绍一些常用的选项。
(1) 进程选择,在ps命令用于选择显示进程的选项包括:“-A”显示所有进程、“-a”显示除了虚拟终端以外的进程、“-C <命令>”显示所有与<命令>有关的进程、“-U <用户1>[,用户2]”显示与指定用户相关的进程、“-u”显示所有有效用户相关的进程、“-t <虚拟终端>”显示与指定虚拟终端相关的进程、-p
(2) 输出选择,在ps命令用于改变输入内容的选项包括:“-f”显示详细列表、“-l”使用长格式显示、“-j”使用作业格式显示、“-o <字符串>”用户自定义格式,使用<字符串>指定字段。<字符串>中可用的字段可以使用“ps -L”命令显示。
2 / 16
张勤
ps命令是用来显示程序执行情况的命令,可以配合kill命令随时中断、删除不必要的程序。下面看几个ps命令的例子。
aux是ps命令常用的选项组合。
[root@srv ~]# ps -aux
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.7/FAQ
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 2072 624 ? Ss 10:36 0:02 init [5]
root 2 0.0 0.0 0 0 ? S< 10:36 0:00 [migration/0]
root 3 0.0 0.0 0 0 ? SN 10:36 0:00 [ksoftirqd/0]
root 4 0.0 0.0 0 0 ? S< 10:36 0:00 [watchdog/0]
root 5 0.0 0.0 0 0 ? S< 10:36 0:00 [events/0]
root 6 0.0 0.0 0 0 ? S< 10:36 0:00 [khelper]
root 7 0.0 0.0 0 0 ? S< 10:36 0:00 [kthread]
root 10 0.0 0.0 0 0 ? S< 10:36 0:00 [kblockd/0]
al也是ps命令常用的选项组合。
[root@srv ~]# ps -al #
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 T 0 7427 4970 8 77 0 - 2355 finish pts/2 00:00:00 vim
4 R 0 7428 4970 0 77 0 - 1054 - pts/2 00:00:00 ps
在ps命令显示的信息中第1行是标题行,从第2行开始都是进程的信息。每列为一个信息,其中常见的列包括以下几种:
(1) F:这个进程的标志其中“4”表示用户为root。
(2) S、STAT:这个进程的状态。状态包括“R”表示该进程目前正在运行、“S”表示该进程目前正在休眠当中但可被某些信号唤醒、“T”表示该进程目前正被挂起、“Z”表示该进程是疆尸进程、“D”表示该进程不可中断休眠。
(3) PID:这个进程进程ID。
(4) PPID:这个进程的父进程ID。
(5) C、%CPU:这个进程使用的CPU资源百分比。
(6) PRI:这个进程的优先执行序。
(7) NI:这个进程的Nice值。
(8) ADDR:这个进程在内存的哪个部分
(9) SZ:这个进程使用的内存大小。
(10) WCHAN:目前这个进程是否正在运行,如果显示“-”表示正在运行。
(11) TTY:用户登录的虚拟终端,如果显示为“?”表示该进程是一个守护进程。
(12) TIME:这个进程使用CPU的时间。
3 / 16
张勤
(13) CMD、COMMAND:这个进程是由哪个命令引发的。
(14) USER:这个进程属于那个用户。
(15) %MEM:这个进程所占用的物理内存百分比。
(16) VSZ:这个进程使用的虚拟内存量,单位是KB。
(17) RSS:这个进程占用的固定的内存量,单位是KB。
(18) TTY:这个进程是在那个虚拟终端上面运行。如果与虚拟终端无关则显示“?”;如果显示“tty1”~“tty6”是本机的用户进程;如果显示“pts/0”等是由网络连接的其他计算机的进程。
(19) START:这个进程被触发启动的时间。
(20) TIME:这个进程实际使用CPU运行的时间。
pstree:以树状查看进程
pstree命令用于以树状查看进程,该命令语法如下。
pstree [-ahlup]
常用选项:
-a:显示每个程序完整的命令,包括路径、选项等。
-h:显示树状图时,标明现在执行的程序。
-l:采用长列格式显示树状图。
-p:显示树状图的同时,显示进程的PID。
-u:显示树状图的同时,显示该进程所属用户。
pstree命令用ASCII字符显示树状结构,清楚地表达程序之间相互关系。下面看几个pstree命令的例子。
[root@srv ~]# pstree
init─┬─acpid
├─anacron
├─atd
├─crond
├─cupsd
├─2*[dbus-daemon]
├─dbus-launch
├─dhclient
├─gdm-binary───gdm-binary─┬─Xorg
│ └─gnome-session─┬─Xsession
│ └─ssh-agent
├─ksoftirqd/0
4 / 16
张勤
├─pam-panel-icon───
top:显示、管理执行中的程序
top命令用于显示、管理执行中的程序,该命令语法如下。
top [-d <间隔秒数>] [-n <执行次数>] [-p
常用选项:
-d <间隔秒数>:指定top监控程序执行情况的间隔时间。
-n <执行次数>:指定监控信息的更新次数。当达到指定的次数后,top命令就会自动结束并回到命令行。
-p
-b:使用批处理模式。在该模式下top将不接受任何热键输入命令,除非达到选项“n”所指定的执行次数或被强行中止。
-c:显示每个程序完整的命令,包括路径、选项等。
-i:执行top时忽略闲置或已成僵尸的进程。
top命令和ps命令的最大区别在于ps命令显示的进程是在执行ps命令那一时刻系统进程的情况,而top命令会实时的显示系统中进行的情况并提供了对进程的管理功能。在执行top命令后,系统就进入了top命令的情况。在top命令情况中可以使用以下热键进行操作:
(1) ?:显示在top命令中可用的热键。
(2) c:切换显示命令名称和完整命令行。
(3) P:在显示时以CPU占用情况排序。
(4) M:在显示时以内存占用情况排序。
(5) N:在显示时以进程PID排序。
(6) T:在显示时以进程累计使用CPU时间的情况排序。
(7) t:切换显示进程和CPU状态信息。
(8) k:给予进程一个信号。
(9) r:更改进程的nice值(有关nice值见1.1.2 )。
(10) q:退出top命令。
(11) i:忽略闲置和僵死进程。
下面是执行top命令后的情况。
显示“up”系统已启动的时间;“users”目前使用系统的人数;“load average”系统在1、5、10分钟的负载。
top - 17:06:54 up 57 min, 3 users, load average: 0.00, 0.00, 0.04
5 / 16
张勤
显示目前系统的进程信息。“totlal”总进程数;“running”目前在运行的进程数;“sleeping”目前休眠的进程数;“stopped”目前停止的进程数;“zombie”目前的僵尸进程数。
Tasks: 124 total, 2 running, 121 sleeping, 0 stopped, 1 zombie
显示CPU的整体负载。“us”用户占用CPU百分比;“sy”系统占用CPU百分;“ni”用户进程空间内改变过优先级的进程占用CPU百分比;“id”空闲CPU百分比;“wa”等待输入输出的CPU时间百分比。
Cpu(s): 0.0%us, 0.3%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
显示目前物理内存的使用情况。“total”总物理内存;“used”已使用的内存;“free”空闲内存;“buffers”缓冲区占用的内存。
Mem: 515340k total, 492976k used, 22364k free, 47684k buffers
显示目前交换分区的使用情况。“total”总交换分区;“used”已使用的交换分区;“free”空闲交换分区;“cached”用于高速缓存的大小。
Swap: 1052216k total, 0k used, 1052216k free, 324028k cached
目前系统中的进程,第一行是标题行,每行一个进程。每列一个信息:“PID”进程编号;“USER”启动进程的用户;“PR”程序的优先执行顺序,越小越早被执行;“NI”目前的nice值,越小越早被执行;“VIRT”进程占用的虚拟内存值;“RES”进程占用的物理内存值;“SHR”进程使用的共享内存值;“S”进程的状态,其中S表示休眠、R表示正在运行、Z表示全局进程、N表示该进程优先值是负数、D表示不可中断的休眠状态;“%CPU”该进程占用的CPU使用率;“%MEM”该进程占用的物理内存和总内存的百分比;“TIME+”进程启动后占用的总的CPU时间;“COMMAND” 进程启动的命令名称。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5576 root 15 0 2336 1056 816 R 0.2 0.2 0:00.01 top
1 root 15 0 2072 620 532 S 0.0 0.1 0:01.27 init
2 root RT -5 0 0 0 S 0.0 0.0 0:00.00 migration/0
3 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
4 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
5 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 events/0
6 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 khelper
pgrep:根据命令、用户、虚拟终端显示进程
pgrep命令用于根据命令、用户、虚拟终端显示进程,该命令语法如下。
pgrep [-l] [-u <用户>] [-t <虚拟终端>] [-d <分隔符>] [命令]
常用选项:
命令:显示指定命令的进程情况。在指定命令时可以使用“*”之类的范本样式。
-u <用户>:显示指定用户拥有的进程情况。
6 / 16
张勤
-t <虚拟终端>:显示由指定虚拟终端控制的进程情况。
-d <分隔符>:用指定分隔符分隔每个进程,默认情况下使用新行。
-l:显示进程名称及PID。
在使用Linux过程中经常利用进程运行的用户名或命令寻找进程信息,一般的操作是显示所有进程再通过管道使用grep命令筛选信息。有时这样并不能完整的得到所需的信息,不过通过pgrep命令可以实现这样的功能。下面看几个pgrep命令的例子。
3433
3917
4104
3433 sshd
4104 sshd
1 init
2 migration/0
3 ksoftirqd/0
10 kblockd/0
11 kacpid
显示所有root用户拥有进程的程名称及PID。
显示所有sshd进程的程名称及PID。
显示所有ssh开头的进程。
[root@srv ~]# pgrep ssh*
[root@srv ~]# pgrep -l sshd
[root@srv ~]# pgrep -lu root
lsof:查找进程使用的文件或设备
lsof命令用于查找进程使用的文件或设备,该命令语法如下。
lsof [-an] [-u <用户名>] [-c <字符串>] [+d|+D <目录>] [文件名] [-i[46] [协议][@主机名|IPv4地址][:服务|端口]]
常用选项:
文件名:显示打开指定文件的所有进程。
-a:表示两个选项都必须满足时才显示结果。
-n:不将IP转换为主机名。
-c <字符串>:显示COMMAND列中包含指定字符的进程所有打开的文件。
-u <用户名>:显示属于指定用户进程打开的文件。
+d <目录>:显示指定目录下被进程打开的文件。
+D <目录>:显示指定目录及其下所有子目录下被进程打开的文件。
7 / 16
张勤
-i:显示符合条件的的进程,其中“4”、“6”表示IPv4和IPv6;“协议”用于指定是TCP还是UDP;主机名用于指定FQDN;“服务”可以是“/etc/service”文件中已有服务名称。
lsof常用于查找应用程序打开的文件名称和数目。可用于查找出某个特定应用程序将日志数据记录到何处,或者正在跟踪某个问题。下面看几个lsof命令的例子。
显示root用户进程所打开的文件类型为txt的文件。在显示的目前系统进程中,第一行是标题行,每行一个进程。每列一个信息:“COMMAND”进程的名称;“PID”进程编号;“USER”进程所有者;“FD”文件描述符,应用程序通过文件描述符识别该文件,比如cwd、txt等;“TYPE”文件类型;“DEVICE”指定磁盘的名称;“SIZE”文件的大小;“NODE”;i节点“NAME”打开文件的确切名称。
[root@srv ~]# lsof -a -u root -d txt
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
init 1 root txt REG 8,7 38652 4047597 /sbin/init
migration 2 root txt unknown /proc/2/exe
ksoftirqd 3 root txt unknown /proc/3/exe
watchdog/ 4 root txt unknown /proc/4/exe
events/0 5 root txt unknown /proc/5/exe
khelper 6 root txt unknown /proc/6/exe
kthread 7 root txt unknown /proc/7/exe
kblockd/0 10 root txt unknown /proc/10/exe
kacpid 11 root txt unknown /proc/11/exe
udevd 575 root txt REG 8,7 71924 4047504 /sbin/udevd
查看25端口现在运行的情况。
[root@srv ~]# lsof -i :25
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
sendmail 3461 root 4u IPv4 10692 TCP :smtp (LISTEN)
1.1.2 Linux进程管理
查看进程只能了解系统中目前进程的运行情况,Linux还提供了一些方法给用户调整进程执行的顺序、终止进程等等。下面是Linux中一些常见的进程管理方法。
进程调度
Linux内核的一个基本任务就是确保所有的进程有效地共享系统资源,要共享的一个最基本的资源就是CPU,内核决定哪个进程何时在CPU上可执行被称为调度。每个进程都会进入CPU的任务分配中并等待CPU执行,而CPU会根据每个进程的优先级来判定哪个进程比较重要。在CPU执行时会先执行那些优先级比较高的进程。
每个进程都有二个影响其调度的值:优先顺序(priority)这是一个动态值,Linux内核会经常改变这个值;优先级(niceness),这是一个固定值,用户可能调整。在下面的ps命令中“PRI”列就是优先顺序,“NI”列就是优先级。
8 / 16
张勤
[root@srv ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 3996 3994 0 75 0 - 1135 wait pts/1 00:00:00 bash
4 R 0 5445 3996 0 77 0 - 1054 - pts/1 00:00:00 ps
将优先顺序和优先级相加的值就是目录的优先顺序。优先顺序越小时,该进程就可以被CPU优先执行。由于优先顺序是由内核动态产生用户不能修改,所以用户只能去修改优先级,优先级可以是正数,也可以是负数。优先级可以影响优先顺序的值,基本上新的优先顺序是等于老的优先顺序加上优先级产生。但是并不能说老的优先顺序是20,将优先级修改为10后,新的优先顺序就是30,这是因为优先顺序是有内核动态产生的。也就是说优生级可以影响优先顺序,不过最终优先顺序还是要经过内核分析后产生的。
在Linux中,一般用户只能属于自己进程的优生级且只能将优先级调大,只有root才可以任意调整优生级。调整进程优先组的命令主要有以下二个。
(1) nice:启动进程时调整优先级
当进程启动时nice命令用于指定进程的优先级,比如下面的例子中tar在执行时就可以带一个+10的优先级。
这里指定优先级为“-10”是因为优先顺序越小的越有可能被先执行,所以指定为“-10”实际上是给了一个比一般进程更有可能被先执行的值。
[root@srv ~]# nice -10 tar -cvjf 2 /etc/
以下是使用top命令查看进程的结果,tar命令的优先级被配置为10。。
top - 17:11:39 up 3:19, 2 users, load average: 0.57, 0.14, 0.05
Tasks: 89 total, 2 running, 87 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2%us, 12.4%sy, 85.9%ni, 0.0%id, 0.5%wa, 0.0%hi, 1.0%si, 0.0%st
Mem: 515340k total, 509576k used, 5764k free, 67900k buffers
Swap: 1052216k total, 0k used, 1052216k free, 363732k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
9559 root 35 10 9056 6908 364 R 51.0 1.3 0:34.97 bzip2
9558 root 26 10 4108 948 792 S 5.9 0.2 0:03.29 tar
(2) renice:调整正在运行中进程的优先级
renice命令用于调整正在运行中进程的优先级。,比如下面的例子中tar在执行时就可以带一个+10的优先级。
tar命令的进程号是9918。
[root@srv ~]# ps -lu root | grep tar
0 S 0 9918 3996 6 78 0 - 1027 pipe_w pts/1 00:00:00 tar
将进程9918的优先级配置为“-10”。
[root@srv ~]# renice -10 9918
9918: old priority 0, new priority -10
再次查看是优先级已修改。
[root@srv ~]# ps -lu root | grep tar
9 / 16
张勤
0 S 0 9918 3996 4 68 -10 - 1027 pipe_w pts/1 00:00:00 tar
向进程发送信号
Linux系统中通过信号通知进程发生的异常事件,并且把信号作为进程间通信的原始机制。Linux内核通过信号通知进程出了异常行为。Linux中信号有不同种类,不同种类的信号有不同的符号名和整数标识。可以通过“kill -l”列出所有的信号名称及整数标识。kill命令可以用于向其他进程发送自定义信号。该命令语法如下。
kill -<信号名称或信号标识> PID
常用选项:
-<信号名称或信号标识>:需要发送给进程的信号。
PID:进程的PID。
在发送的信号中比较常见的包括:SIGHUP(信号标识为1)重新读取进程的选项;SIGINT(信号标识为2)请求进程中断,“Ctrl+C”也可生成该信号;SIGKILL(信号标识为9)强制进程中断;SIGTERM(信号标识为15)请求进程终止,与SIGKILL的差别在于15是以正常的方式关闭程序;SIGTSTP(信号标识为20)挂起进程,“Ctrl+Z”也可生成该信号。下面看几个kill命令的例子。
vim命令的进程号是10992。
[root@srv ~]# ps -lu root | grep vim
0 S 0 10992 3996 0 75 0 - 2366 - pts/1 00:00:00 vim
强制中断vim的进程。
[root@srv ~]# kill -9 10992
vim命令已被关闭。
[root@srv ~]# ps -lu root | grep vim
top的进程号是11053。
[root@srv ~]# ps -lu root | grep top
4 S 0 11053 3996 0 84 0 - 576 - pts/1 00:00:00 top
使用正常方式退出top命令。
[root@srv ~]# kill -SIGTERM 11053
[root@srv ~]# ps -lu root | grep top
用kill命令发送信号控制进程是Linux中一个很常见的操作,除了kill命令以外Linux还提供了一个pkill命令。在使用kill命令时用户必须知道进程的PID,而pkill命令可以根据条件向进程发送信号。该命令语法如下。
pkill -<信号名称或信号标识> [-n] [-u <用户>] [-t <虚拟终端>] [进程匹配条件]
常用选项:
-<信号名称或信号标识>:需要发送给进程的信号。
-n:只选择最新启动匹配进程。
10 / 16
张勤
-u <用户>:选择指定用户的进程。
-t <虚拟终端>:只选择由指定虚拟终端控制的进程。
进程匹配条件:使用正则表达式匹配进程名称。
pkill命令可以发送的信号与kill相同,下面看几个pkill命令的例子。
查看用户jack的所有进程。
[root@srv ~]# ps -lu jack
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
5 S 500 12724 12722 0 75 0 - 2481 - ? 00:00:00 sshd
0 S 500 12725 12724 0 75 0 - 1135 wait pts/3 00:00:00 bash
0 S 500 12845 12725 0 76 0 - 2366 - pts/3 00:00:00 vim
向用户jack所属进程中进程名以“v”开头的发送SIGKILL信号。
[root@srv ~]# pkill -9 -u jack ^v
“v”开头的已经被中断。
[root@srv ~]# ps -lu jack
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
5 S 500 12724 12722 0 75 0 - 2481 - ? 00:00:00 sshd
0 S 500 12725 12724 0 75 0 - 1135 - pts/3 00:00:00 bash
向用户jack所属的所有进程发送SIGKILL信号。
[root@srv ~]# pkill -9 -u jack
用户jack所属的所有进程已经被中断。
[root@srv ~]# ps -lu jack
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
Linux还提供一个killall命令,该命令可以将信号发由命令名指定的进程。killall命令在指定命令名时默认是区分大小写的,可以使用“-I”选项让该命令忽略大小写。比如下面的例子中使用该命令中断所有vim的进程。
查看用户jack的所有进程。
[root@srv ~]# ps -lu jack
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
5 S 500 4043 4041 0 75 0 - 2481 - ? 00:00:00 sshd
0 S 500 4044 4043 0 75 0 - 1135 wait pts/2 00:00:00 bash
5 S 500 4082 4080 0 75 0 - 2481 - ? 00:00:00 sshd
0 S 500 4083 4082 0 75 0 - 1135 wait pts/3 00:00:00 bash
0 S 500 4125 4044 0 77 0 - 2366 - pts/2 00:00:00 vim
0 S 500 4126 4083 1 77 0 - 2366 - pts/3 00:00:00 vim
中断所有vim命令的进程。
[root@srv ~]# killall vim
[root@srv ~]# ps -lu jack
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
11 / 16
张勤
5 S 500 4043 4041 0 82 0 - 2481 - ? 00:00:00 sshd
0 S 500 4044 4043 0 82 0 - 1135 - pts/2 00:00:00 bash
5 S 500 4082 4080 0 75 0 - 2481 - ? 00:00:00 sshd
0 S 500 4083 4082 0 75 0 - 1135 - pts/3 00:00:00 bash
1.2 Linux作业管理
Linux是一个多任务的操作系统,但是在bash Shell中如果不特别指定,命令会在前台执行。也就是说当开始执行一个命令时,必须要等待该命令执行完成后才可以输入下一个要执行的命令。通过给命令附加一个“&”,可以将命令放入后台执行。通常只有那些不需要输入且不会生成大量输出的长时间的命令才适合在后台运行,比如复制一个比较大的文件。在下面的例子中将一个打包/etc目录的命令放入后台运行,但是由于tar命令会产生一些输出信息,为了不影响正常的使用将这些信息导入到/dev/null中。
提示:/dev/null是Linux中的一个黑洞,被放入的任何东西都会消失。
[root@srv ~]# tar -cvjf 2 /etc &>/dev/null &
[1] 4465 #作业号和进程ID。
使用“&”将命令放入后台执行后会显示二个信息:作业号和进程ID。在上面的例子中作业号是“1”、进程ID是“4465”
使用“Ctrl+Z”可以将正在运行的程序挂起并放入后台,同时也会显示作业号和进程ID。比如打开vim后使用“Ctrl+Z”可以将vim挂起并放入后台。
在使用“&”或“Ctrl+Z”方式将有多个进程放入后台运行时,可以通过“jobs”命令查看。默认情况下jobs命令只显示作业号,使用“-l”后会连同PID一起显示。
[root@srv ~]# jobs -l
[1]- 4566 Stopped (tty output) vim
[2]+ 4580 Stopped (tty output) top
[3] 4581 Done tar -cvjf 2 /etc >&/dev/null
如果希望将后台的作业置于前台可以使用“fg <作业号>”命令。在下面的使用中使用fg命令将作业叫为1的进程置于前台运行。
[root@srv ~]# fg 1
如果希望取消作业可以使用“kill %<作业号>”命令。在下面的例子中使用kill命令取消作业号为1的作业。
[root@srv ~]# jobs -l
[1]- 5029 Running tar -cvjf 2 /etc >&/dev/null &
[2]+ 5044 Stopped (tty output) vim
[root@srv ~]# kill %1
[root@srv ~]# jobs -l
[2]+ 5044 Stopped (tty output) vim
1.3 自动化任务管理
在日常服务器的维护过程经常会一些重复的工作需要在指定的时间内完成,比如备份等,
12 / 16
张勤
如果每次做这样的工作时都需要用户进行操作就比较麻烦,在Windows中可以通过任务计划完成这样一些周期性的工作,在Linux中也有类似的功能,下面将讲述在Linux中二种实现在指定时间完成指定任务的方法。
1.3.1 一次性任务管理
一次性任务是指在未来某个时间需要执行一次的一个或多个命令,在Linux中可以通过at命令定义这样的任务,使用该命令将要确保“atd”服务是运行状态,该命令语法如下。
at [-lm] [-d <任务编号>] [-f <文件>] [-q <队列>] [日期时间]
常用选项:
日期时间:指定执行任务的日期时间。
-d <任务编号>:将要执行的任务删除,与直接执行atrm命令作用相同。
-f <文件>:从指定的文件中读取要执行的任务,而不是输入要执行的任务。
-q <队列>:使用指定的队列,队列是以单一英文字符给分,其顺序是从小写a到z,再从大写A到Z。顺序越后的表示工作优先级越高,at命令默认的队列是a队列。
-l:显示已定义的任务,与直接执行atq命令作用相同。
-m:工作完成后,将结果以Email返回。
在at命令中表示日期时间可以采用以下几种形式:
(1) HH:MM:在今天的HH:MM执行任务,如果该时间已超过现在的时间,则表示是明天的HH:MM执行任务。比如目前是15:30,使用“at 16:00”表示定义的任务将在明天16:00执行。
(2) HH:MM YYYY-MM-DD:指定某年某月的某天执行任务,比如使用“at 21:30
2012-12-31”表示定义的任务将在2012年12月31日21:30分执行。
(3) HH:MM[am|pm] + 数字 [minutes|hours|days|weeks]:在某个时间点再过指定时间后执行,比如使用“at now + 3 days表示定义的任务在从今天算起过3天后执行,使用“at 04pm + 4 hours”表示定义的任务在20点执行。
在RHEL 5.x中默认情况下所有用户都可以使用at命令,但可以通过/etc/(默认不在在,需要手动建立)和/etc/文件定义允许或禁止使用at命令的用户,在这二个文件中定义用户时,每行一个用户名。当用户使用at命令时,如果/etc/文件存在,且用户名在该文件中时(不论该用户名是否在/etc/中)用户就可以使用at命令;如果/etc/文件不存在,系统会检查/etc/文件,如果用户名在该文件中用户就不能使用at命令;如果二个文件都不存在只有root用户可以使用at命令。
在使用at命令时,系统会进入该命令的输入界面,用户每输入完成一个要执行的命令后回车,当定义完成后可使用“Ctrl+D”保存退出,下面看几个at命令的例子。
当前用户是root。
[root@srv ~]# id
13 / 16
张勤
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
定义一个在今天21:30分执行的任务。
[root@srv ~]# at 21:30
#以下二句是定义的任务内容。
at> service httpd restart
at> service mysqld restart
at>
job 2 at 2010-03-01 21:30
显示当前的一次性任务,第一列是任务编号;第二、三列是任务执行的日期时间;第四列是任务队列;第五列是定义任务的用户。在显示的内容中任务2是上一句at命令定义的任务,由于当前用户是root所以在显示任务时会显示所有用户定义的任务,如果是一般用户只能查看到自己的任务。
[root@srv ~]# at -l
2 2010-03-01 21:30 a root
1 2010-03-01 15:44 a jack
删除任务编号为1的任务,由于当前用户是root所在可以删除其他用户定义的任务,如果是一般用户只能删除自己定义的任务。
[root@srv ~]# at -d 1
[root@srv ~]# at -l
2 2010-03-01 21:30 a root
1.3.2 周期性任务管理
at命令只能定义在未来执行一次的任务,而crontab可以定义一个周期性的任务,比如每月10号执行,使用该命令将要确保“crond”服务是运行状态,该命令语法如下。
crontab [-u <用户>] [配置文件] [-elr]
常用选项:
配置文件:指定执行任务的日期时间。
-u <用户>:为指定用户定义周期性的任务,只有root用户才可以为其他用户定义,而一般用户只能定义自己的周期性的任务。
-e:编辑指定用户的周期性的任务。
-l:显示指定用户的周期性的任务。
-r:删除指定用户的周期性的任务。
在RHEL 5.x中默认情况下所有用户都可以使用crontab命令,但可以通过/etc/(默认不在在,需要手动建立)和/etc/文件定义允许或禁止使用crontab命令的用户,在这二个文件中定义用户时,每行一个用户名。当用户使用crontab命令时,如果/etc/文件存在,且用户名在该文件中时(不论该用户名是否在/etc/中)用户就可以crontab命令;如果/etc/文件不存在,系统会检查/etc/文件,如果用户名在该文件中用户就不能使用crontab命令;如果二个文件都不存在只有root用户
14 / 16
张勤
可以使用crontab命令。所有用户可以使用“crontab -e”命令编辑自己周期性的任务;root用户可以“crontab -e -u <用户>”编辑其他用户的的周期性的任务。在使用“crontab -e”后系统会进入一个类似vim的编辑环境,使用“i”开始编辑。每一行是一个任务,一行必需包括6列,每列之间至少使用一个空格分隔。每列分别表示“分钟 小时 日期 月份 星期 要执行的命令”,分钟可用值包括0~59、小时可用值包括0~24、日期可用值包括1~31、月分可用值包括1~12、星期可用值包括0~7,其中0和7都表示星期天,在这些表示时间的列中还可以使用“*”表示任何时间、使用“,”分隔多个时间、使用“-”表示时间段、使用“*/n”表示每隔多少时间,下面看几个使用“crontab -e”命令编辑的例子。
每周1执行“/bin/cp -r /boot/grub /bootbak”命令。
* * * * 1 /bin/cp -r /boot/grub /bootbak
每隔10分钟执行“/bin/updatedb”命令。
*/10 * * * * /bin/updatedb
9月到12月的12点、17点、20点执行“/sbin/reboot”命令。
* 12,17,20 * 9-12 * /sbin/reboot
使用“crontab -e”命令编辑周期性的任务后,还可以使用crontab命令的其他选项进行周期性的任务的管理,下面看几个crontab命令的例子。
当前用户是root。
[root@srv ~]# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
查看当前用户周期性的任务。
[root@srv ~]# crontab -l
* 23 * * 1-5 /sbin/reboot
查看用户jack周期性的任务。
[root@srv ~]# crontab -l -u jack
* * * * 2 clear
删除用户jack周期性的任务。
[root@srv ~]# crontab -r -u jack
[root@srv ~]# crontab -l -u jack
no crontab for jack
在Linux系统中除了用户定义的周期性任务以外,系统自身也定义了很多周期性任务。这些系统自身的周期性任务定义在/etc/crontab文件中,其中各行作用如下。
①:定义使用的Shell。
②:定义命令的搜索路径。
③:定义当以下的周期性任务有需要输出的内容时,将信息发送给root用户。
④:定义根目录。
⑤:定义每小时需执行的任务是/etc/目录中的脚本。
15 / 16
张勤
⑥:定义每天需执行的任务是/etc/目录中的脚本。
⑦:定义每周需执行的任务是/etc/目录中的脚本。
⑧:定义每月需执行的任务是/etc/y目录中的脚本。
[root@srv ~]# cat /etc/crontab
SHELL=/bin/bash ①
PATH=/sbin:/bin:/usr/sbin:/usr/bin ②
MAILTO=root ③
HOME=/ ④
# run-parts
01 * * * * root run-parts /etc/ ⑤
02 4 * * * root run-parts /etc/ ⑥
22 4 * * 0 root run-parts /etc/ ⑦
42 4 1 * * root run-parts /etc/y ⑧
系统默认在这些目录会有一些脚本,用户也可以将自己的脚本放到对应目录中,这样到了指定的时间也会被执行。如果到了指定的时间这些脚本因为一些原因未执行,比如当时未开机,系统会根据/etc/anacrontab文件中的定义重新尝试执行。
[root@srv ~]# cat /etc/anacrontab
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
1 65 run-parts /etc/
7 70 run-parts /etc/
30 75 y run-parts /etc/y
在该中“MAILTO=root”之后的行就是定义重新尝试执行的方式,每行是一种方式。每行中第一列表示重新尝试执行的最长时间;第二列表示重新尝试执行的延时时间;第三列是描述信息;第四列表示要执行的内容。比如“1 65 run-parts /etc/”表示每65分钟重试一次每天要执行的任务,重试1天后就不执行了。
16 / 16
发布者:admin,转转请注明出处:http://www.yc00.com/web/1690379631a340703.html
评论列表(0条)