进程,是一个正在运行的程序的实例。

操作系统在启动时创建init进程,它是所有进程的父进程,进程ID是1,在启动其他程序时系统为每个程序分配一个惟一的进程标识符,称为PID。

在后台,使用frok函数调用和execve系统调用来启动新程序,这些调用将复制当前运行程序以得到子进程,从面产生分叉(fork),子进程是正在运行的程序的精确副本。分叉得到的程序具有一个新的PID和不同的父进程ID,并且系统传颂重置子进程的资源。

相对于产生子进程,用户还可能用一个新进程来代替当前正在运行的进程。Unix shell含有内置的exec命令,该命令用一个新程序来代替正在运行的shell(在后台,这个命令使用execve系统调用)。

进程ID是按从小到大的顺序依次分配的,当进程停止时,可以重复使用以前用过的PID。通常情况下,PID的取值范围从1到32768。有些具有64位的PID或者更大。

要查看分配给shell的PID可以使用shell变量$,例如:

%echo $$

23527

输出的23527就是正在运行的命令行shell的PID

文件系统的属性指示了文件是否可以执行以及哪些人有权限执行该文件(文件的所有者、拥有该文件的组成员或者每个人)。file命令可以告诉用户文件是否可执行。

shell脚本

用户还可以拥有可执行文件,它们在编写时就可以执行,而不必用编程代码编写。在加载这种程序时,文件的第一个字符说明了该文件是哪种类型的可执行格式。字符#!告诉内核运行在#!之后列出的程序,包括根据需要设置命令行参数。然后该文件就变成正在运行的解释程序所使用的输入。

例如:

#!/bin/cat

Hello World

然后保存为cat.script,然后使用chmod a+x cat.script命令使文件可执行

运行该文件

./cat.script

这个脚本的输入就是文件本身,因为cat命令显示它的内容。

正在运行的进程

通过ps命令可以查看用户所拥有的进程。不带任何参数单独运行ps命令将显示用户所拥有的进程,这些进程与一个终端相关联。对于查看同一个系统上的不同用户正在运行的进程,ps工具非常有用。还可以使用该命令查看是哪个进程耗尽了内存或过多占用了cpu。

ps在语法上有两种不同的风格,一种是BSD系统上使用的,另一种是Unix system V实现,这两种ps用法的主要差别在于是否使用-作为先期的前缀。标准的BSD选项不使用破折号例如

ps $$

而System V风格的ps实现同样式功能则使用破折号。

ps -p $$

可以使用这两种方法来确定自己的ps所用的语法

进程属性

每个进程都有一个具有多种属性的环境,这些属性包括命令行参数、用户环境变量、文件描述符、工作目录、文件创建掩码、控制终端(控制台)、资源利用等,其中很多属性都可以和父进程共享。

要查看各种进程属性,用户可以使用ps -o开关,它可以用于两种风格的ps。

停止进程

有几种不同的方法可以结束进程。

通常情况下,从基于控制台的命令界面发送ctrl+c(默认的中断字符)将退出命令。但有时候进程会捕获或忽略中断字符。

用于结束进程的标准工具是kill。从技术角度讲,kill没有杀死一个进程,只是向进程发送一个特殊的信号。kill的默认信号是SIGTERM。用户试图停止的软件在收到TERM信号时可能会完全备份文件或者停止工作,但是这些操作也许并不会发生。

使用kill只需要将进程ID作为命令参数即可。

kill 5432

还可以通过名字来选择信号,将-作为信号名的前缀(信号名的SIG部分是可选的)

kill -SIGTERM 5432

信号也可以通过编号来识别,可以运行kill -l显示所包含的信号。

僵死进程

通常,结束一个子进程会通过SIGCHLD信号告诉它的父进程。然后父进程可以根据需要执行一些其他的任务或者重启一个新的子进程。但是有时候会终止父进程。在这种情况下,“所有进程的父进程”,init,将变成新的PPID。经常会能够遇到一些进程的PPID是1,可能就是这种情况。

在结束一个进程后,ps列表可能仍然显示该进程,标识为z状态。这是一个僵死的或者已死的进程。该进程已经死亡,没有在使用。这种情况极少出现,即使向它们发送-SIGKILL信号。

如果一个进程处于挂起状态,可以首先试着向它发送两个-SIGTERM信号。如果该进程仍然没有退出,可以尝试发送-SIGKILL信号。如果进程依然拒绝结束,可能需要重启系统。

top命令

对于快速显示按照各种标准排序的进程,top命令非常有用。它是一个交互式的诊断工具,会经常进行更新,显示有关物理和虚拟内存、CPU的使用情况、负载均衡和忙进程的信息。top的不同实现提供了不同的信息,并且具有用于交互行为的不同按键。通常情况下top命令在显示进程时,会将占用大部分CPU的进程显示在列表的顶端。这是可以定制的。

/proc 文件系统

/proc文件系统是一个动态产生的文件系统,它能够用于检索正在系统上运行的进程的相关信息。还可以用于检索和设置其他内核级的配置,这取决于Unix系统。Linux和Solaris系统提供了/proc文件系统,其他Unix系统也可以使用/proc文件系统,但是通常没有默认安装。

/proc文件系统包含了以PID为名称的活动进程的目录项。这些目录中包含了提供各种进程属性的文件。使用/proc文件系统能够查看进程所使用的文件描述符、命令名、实际正在运行的可执行文件、定义的环境变量等。

 setuid和setgid

当文件具有执行时设置用户ID或执行时设置组ID的模式集时,程序能以增强的功能运行。如果一个程序为根用户所有,并且设置了设置用户ID模式位,那么当普通用户运行该程序时,它将具有增强的(根)权限。

例如:

-r-xr-sr-x 1 root operator 23336  23  sep 2003 /bin/df

-r-sr-xr-x 3 root wheel     41480  25  sep 2003 /user/bin/chsh

输出是标准的ls长列表格式(ls -l)。用户和组的执行位用小写字母s表示,说明它们分别是setuid和setgid。

输出说明存在许多有用的管理工具,它们放在setuid和setgid之后作为一个整体使用。

setgid df 命令使得用户拥有操作人员组一样的权限,因此它能够查看那些只对操作人员组中的成员可读的磁盘设备。

日常工作中会用到许多其他的setuid和setgid软件。用户可以使用find工具来列出系统上的这些软件。

sudo find / -perm -4000 -print

该命令列出具有执行时设置用户ID位集的所有文件。

setuid和setgid软件可能导致潜在的安全问题。应该仔细编写和审计setuid和setgid软件。因为存在一些会利用shell脚本及其环境的技术,所以大多数Unix系统都不支持setuid。安全使用setuid和setgid功能的主要方法是使用细粒度的组,这些组拥有用户需要对其进行读取和写入的目录和/或文件(包括设备)例如,可以将用户数据库分成很多单独的文件,其中一些允许用户对其修改。

shell作业控制

Unix命令行shell可以用于在后台运行程序,用户能够同时运行多个程序,还可以用于挂起命令以及重新启动挂起的命令。要让shell在后台运行特定的命令,只需要简单地向命令行的末尾追加一个&。例:要在后台运行sleep

$ sleep 60 &

[1] 16556

$

该命令使得sleep命令运行60秒。sleep工具等待一定的时间后成功退出。通过使用&将显示下一个命令行shell提示符,该提示符可以立刻用于其他命令。括号内的1是作业编号,16556是进程ID,这些信息是由shell而不是sleep命令显示的。

大多数的shell具有内置jobs命令,可以显示正在运行的shell作业

$ jobs

[1]+ Running                    sleep  60  &

在后台运行的命令不需要等待控制台的输入,但是可以向控制输出文本。在前台运行的命令可以拥有完整的交互。

可以使用内置的fg命令将一个作业从后台转到前台。可以使用编号作为fg的参数。

$ fg  1

sleep 60

一旦将一个命令转到前台,系统将不会显示shell提示符,直到该进程结束时为止,并且直到此时用户才能运行另一个命令。

shell还使得能够通过按下默认的挂起按键组合ctrl+z来挂起一个当前正在运行的前台进程。

-bash-3.00$ sleep 60 &
[1] 1476
-bash-3.00$ jobs
[1]+  Running                 sleep 60 &
-bash-3.00$ fg 1
sleep 60
^Z
[1]+  Stopped                 sleep 60
-bash-3.00$ jobs
[1]+  Stopped                 sleep 60
 

还可以终止shell作业。大多数内置的kill命令,该命令用百分号引用作业编号而不是PI

D。还可以通过向进程发送信号23(SIGSTOP)来挂起一个进程,然后通过发送信号25(SIGCONT)解除挂起。

-bash-3.00$ sleep 120 &
[1] 1574
-bash-3.00$ jobs
[1]+  Running                 sleep 120 &
-bash-3.00$ kill -23 %1
-bash-3.00$ jobs
[1]+  Stopped                 sleep 120
-bash-3.00$ kill -25 %1
-bash-3.00$ jobs
[1]+  Running                 sleep 120 &
 

当用户无法使用ctrl+z挂起时,使用kill命令来挂起进程和解除对进程的挂起是很有用的。