[笔记]快乐的Linux命令行《十》进程

169 阅读9分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

@TOC

前言

通常,现在的操作系统都支持多任务,意味着操作系统(给用户)造成了一种假象,(让用户觉得) 它同时能够做多件事情,事实上,它是快速地轮换执行这些任务的。(时间轮片机制运行)

Linux 内核通过使用进程,来管理多任务。通过进程,Linux 安排不同的程序等待使用 CPU。有时候,计算机变得呆滞,运行缓慢,或者一个应用程序停止响应。在这一章中,我们将看一些可用的命令行工具,这些工具帮助我们查看程序的执行状态,以及怎样终止行为不当的进程。

这一章将介绍以下命令:

  • ps –报告当前进程快照
  • top –显示任务
  • jobs –列出活跃的任务
  • bg –把一个任务放到后台执行
  • fg –把一个任务放到前台执行
  • kill –给一个进程发送信号
  • killall –杀死指定名字的进程
  • shutdown –关机或重启系统

一、进程

Linux启动过程:

  1. 当系统启动的时候,内核先把一些它自己的程序初始化为进程
  2. 然后运行一个叫做init 的程序
  3. init,依次地,再运行一系列的称为 init 脚本的 shell 脚本(位于/etc),它们可以启动所有的系统服务。

其中许多系统服务以守护(daemon)程序的形式实现,守护程序仅在后台运行,没有任何用户接口。

这样,即使我们没有登录系统,至少系统也在忙于执行一些例行事务。

1.1 进程是怎样工作的

一个程序可以发动另一个程序,这个事实在进程方案中,表述为一个父进程创建了一个子 进程。

内核维护每个进程的信息,以此来保持事情有序。

例如,系统分配给每个进程一个数字,这个数字叫做进程 IDPID

PID 号按升序分配,init 进程的 PID 总是 1。

内核也对分配给每个进程的内存进行跟踪。

像文件一样,进程也有所有者和用户 ID有效用户 ID,等等。

1.2 查看进程

查看进程,最常使用地命令(有几个命令)是 ps

ps 程序有许多选项,它最简单地使用形式是这样的:

[me@linuxbox ~]$ ps
PID TTY TIME CMD
5198 pts/1 00:00:00 bash
10129 pts/1 00:00:00 ps

列出了两个进程,进程 5198 和进程 10129,各自代表命令 bash 和 ps。

默认情况下,ps 不会显示很多进程信息,只是列出与当前终端会话相关的进程

ps 命令运行结果的其它字段。

TTY 是 “Teletype” 的简写,是指进程的控制终端

TIME 字段表示进程所消耗的 CPU 时间数量

“ps x”组合

ps 命令加上选项,我们可以得到更多关于系统运行状态的信息:

[me@linuxbox ~]$ ps x
PID TTY STAT TIME COMMAND
2799 ? Ssl 0:00 /usr/libexec/bonobo-activation-server – ac
2820 ? Sl 0:01 /usr/libexec/evolution-data-server-1.10 --
and many more...

加上 “x” 选项(注意没有开头的”-“ 字符),ps 命令,展示所有进程,不管它们由什么终端(如果有的话)控制。在 TTY 一栏中出现的 “?” ,表示没有控制终端。使用这个 “x” 选项,可以看到我们所拥有的每个进程的信息。

输出结果中,新添加了一栏,标题为 STAT

STAT 是 “state” 的简写,它揭示了进程当前状态

image.png

ps+less组合

因为系统中正运行着许多进程,所以 ps 命令的输出结果很长。

这经常很有帮助,要是把 ps的输出结果管道到 less 命令,借助 less 工具,更容易浏览。

一些选项组合也会产生很长的输出结果,所以最大化终端仿真器窗口,也是一个好主意。

"ps aux" 组合

另一个流行的选项组合是 “aux”(不带开头的 “-” 字符)。

这会给我们更多信息:

[me@linuxbox ~]$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2136 644 ? Ss Mar05 0:31 init
root 2 0.0 0.0
0
0 ? S< Mar05 0:00 [kt]
and many more...

这个选项组合,能够显示属于每个用户的进程信息。使用这个选项,可以唤醒“BSD 风格” 的输出结果。

Linux 版本的 ps 命令,可以模拟几个不同 Unix 版本中的 ps 程序的行为。

通过这些选项,我们得到这些额外的列。

image.png

1.3 用 top 命令动态查看进程

为了看到更多动态的信息,我们使用 top 命令:

[me@linuxbox ~]$ top

top 程序连续显示系统进程更新的信息(默认情况下,每三分钟更新一次).

“top” 这个名字来源于这个事实,top 程序是用来查看系统中“顶端”进程的。

top 显示结果由两部分组成:

  • 最上面是系统概要,
  • 下面是进程列表,以 CPU 的使用率排序。

image.png

其中系统概要包含许多有用信息。

下表是对系统概要的说明:

image.png

top 程序接受一系列从键盘输入的命令。两个最有趣的命令是 h 和 q。h,显示程序的帮助屏幕,q,退出 top 程序。

两个主要的桌面环境都提供了图形化应用程序,来显示与 top 程序相似的信息(和Windows 中的任务管理器差别不多),但是我觉得 top 程序要好于图形化的版本,因为它运行速度快,并且消费很少的系统资源。毕竟,我们的系统监测程序不能成为系统怠工的源泉,而这是我们试图追踪的信息。

1.4 控制进程

1.5 中断一个进程

在一个终端中,输入 Ctrl-c,中断一个程序

这意味着,我们礼貌地要求终止这个程序。

输入 Ctrl-c 之后,xlogo 窗口关闭,shell 提示符返回。

1.6 把一个进程放置到后台(执行)

方式一 命令结尾加&

比方说,我们想让 shell 提示符返回,却没有终止 xlogo 程序。

为达到这个目的,我们把这个程序放到后台执行。把终端看作是一个有前台(表层放置可见的事物,像 shell 提示符)和123后台(表层之下放置隐藏的事物)(的设备)。

启动一个程序,让它立即在后台运行,我们在程序命令之后,加上 “&” 字符:

[me@linuxbox ~]$ xlogo &
[1] 28236
[me@linuxbox ~]$

工作控制,这个 shell 功能可以列出从终端中启动的任务。

执行 jobs 命令,我们可以看到这个输出列表:

[me@linuxbox ~]$ jobs
[1]+ Running xlogo &

结果显示我们有一个任务,编号为“

1”,它正在运行,并且这个任务的命令是 xlogo &。

方式二 nohup命令

nohup 英文全称 no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。

nohup 命令,在默认情况下(非重定向时),会输出一个名叫 nohup.out 的文件到当前目录下,如果当前目录的 nohup.out 文件不可写,输出重定向到  $HOME/nohup.out 文件中

 nohup Command [ Arg … ] [ & ]

Command:要执行的命令。

Arg:一些参数,可以指定输出文件。

& :让命令在后台执行,终端退出后命令仍旧执行。

1.示例一:在后台执行 root 目录下的 runoob.sh 脚本:

nohup /root/runoob.sh &

这时我们打开 root 目录 可以看到生成了 nohup.out 文件。

2.示例二:命令在后台执行 root 目录下的 runoob.sh 脚本,并重定向输入到 runoob.log 文件

nohup /root/runoob.sh > runoob.log 2>&1 &

2>&1 解释(之前提到标准输出和错误输出):

将标准错误 2 重定向到标准输出 &1 ,标准输出 &1 再被重定向输入到 runoob.log 文件中。

  • 0 – stdin (standard input,标准输入)
  • 1 – stdout (standard output,标准输出)
  • 2 – stderr (standard error,标准错误输出)

方式三 安装第三方软件 例如screen

screen命令用于多重视窗管理程序。

screen为多重视窗管理程序。此处所谓的视窗,是指一个全屏幕的文字模式画面。

通常只有在使用telnet登入主机或是使用老式的终端机时,才有可能用到screen程序。

screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s <shell>][-S <作业名称>]

示例:

创建 screen 终端

# screen //创建 screen 终端

创建 screen 终端 并执行任务

# screen vi ~/main.c //创建 screen 终端 ,并执行 vi命令

离开 screen 终端

# screen vi ~/main.c //创建 screen 终端 ,并执行 vi命令

#include 

main ()
{

}

"~/mail.c"       0,0-1    

在 screen 终端 下 按下 Ctrl+a d键

重新连接离开的 screen 终端

# screen -ls  //显示已创建的screen终端 
There are screens on:
2433.pts-3.linux    (2013年10月20日 16时48分59秒)    (Detached)
2428.pts-3.linux    (2013年10月20日 16时48分05秒)    (Detached)
2284.pts-3.linux    (2013年10月20日 16时14分55秒)    (Detached)
2276.pts-3.linux    (2013年10月20日 16时13分18秒)    (Detached)
4 Sockets in /var/run/screen/S-root.

# screen -r 2276 //连接 screen_id 为 2276 的 screen终端

1.7 进程返回到前台

一个在后台运行的进程对一切来自键盘的输入都免疫,也不能用Ctrl-c来中断它。

使用 fg命令,让一个进程返回前台执行:

[me@linuxbox ~]$ jobs
[1]+ Running  xlogo &
[me@linuxbox ~]$ fg %1
xlogo

fg 命令之后,跟随着一个百分号和工作序号(叫做 jobspec)。

如果我们只有一个后台任务,那么 jobspec 是可有可无的。输入 Ctrl-c 来终止 xlogo 程序。

1.8 停止一个进程

有时候,我们想要停止一个进程,而没有终止它。这样会把一个前台进程移到后台等待。

输入 Ctrl-z,可以停止一个前台进程。

让我们试一下。在命令提示符下,执行 xlogo 命令,然后输入 Ctrl-z:

1.9 通过 kill 命令给进程发送信号

kill 命令被用来给程序发送信号。

语法形式:

kill [-signal] PID...

如果在命令行中没有指定信号,那么默认情况下,发送 TERM(终止)信号

kill 命令被经常用来发送以下命令:

image.png image.png

kill -Num 发送信号

[me@linuxbox ~]$ xlogo &
[1] 13546
[me@linuxbox ~]$ kill -1 13546
[1]+ Hangup xlogo

在这个例子里,我们在后台启动 xlogo 程序,然后通过 kill 命令,发送给它一个 HUP 信号。

这个 xlogo 程序终止运行,并且 shell 指示这个后台进程已经接受了一个挂起信号。

在看到这条信息之前,你可能需要多按几次 enter 键。

注意,既可以用号码,也可以用名字,不过要在名字前面加上字母“SIG”,来指定所要发送的信号

[me@linuxbox ~]$ xlogo &
[1] 13546
[me@linuxbox ~]$ kill -1 13546
[1]+ Hangup
xlogo

重复上面的例子,试着使用其它的信号。记住,你也可以用 jobspecs 来代替 PID。进程,和文件一样,拥有所有者,所以为了能够通过 kill 命令来给进程发送信号,你必须是进程的所有者(或者是超级用户)。

以下是其它一些常用信号列表:

image.png

1.10 通过 killall 命令给多个进程发送信号

通过 killall 命令,给匹配特定程序或用户名的多个进程发送信号

语法形式:

killall [-u user] [-signal] name..

为了说明情况,我们将启动一对 xlogo 程序的实例,然后再终止它们:

[me@linuxbox ~]$ xlogo &
[1] 18801
[me@linuxbox ~]$ xlogo &
[2] 18802
[me@linuxbox ~]$ killall xlogo
[1]- Terminated
xlogo
[2]+ Terminated
xlogo

和 kill 命令一样,你必须拥有超级用户权限才能给不属于你的进程发送信号。

1.11 更多和进程相关的命令

因为监测进程是一个很重要的系统管理任务,所以有许多命令与它相关。

玩玩下面几个命令:

image.png

image.png

总结

这章节我们学会了:

  • 进程相关命令
  • 如何查看进程(ps,top)
  • 如何关闭一个进程(cirl-c
  • 如何启动一个后台进程(&,nohup,screen
  • 如何查看后台进程(job
  • 如何使后台进程返回到前台(fg %Num)
  • 如何停止一个前台进程(Ctrl-z)
  • 如何杀死一个进程(kill,killall