这个 -u 和 -a 选项提供附加信息。 有关更多选项及其作用,请参阅信息页面。
在下一节中,我们将看到一个进程如何创建另一个进程。
4.1.5. 一个进程的生死
4.1.5.1. 流程创建
创建新进程是因为现有进程制作了其自身的精确副本。 该子进程与其父进程具有相同的环境,只是进程 ID 号不同。 这个过程叫做 分叉.
在 fork 进程之后,子进程的地址空间被新的进程数据覆盖。 这是通过一个 EXEC 调用系统。
这个 分叉执行 机制因此用新命令切换旧命令,而执行新程序的环境保持不变,包括输入和输出设备的配置、环境变量和优先级。 此机制用于创建所有 UNIX 进程,因此它也适用于 Linux 操作系统。 即使是第一个过程, 初始化,进程 ID 为 1,在引导过程中分叉
所谓 引导 的程序。
该方案说明了 fork-and-exec 机制。 fork 过程后进程 ID 发生变化:
图 4-1。 分叉执行机制
有几种情况 初始化 成为进程的父进程,而进程不是由 初始化,正如我们在 ptree 例子。 例如,许多程序, 守护进程 它们的子进程,因此它们可以在父进程停止或正在停止时继续运行。 窗口管理器就是一个典型的例子; 它开始了 xterm的 生成接受命令的 shell 的进程。 然后窗口管理器拒绝任何进一步的责任并将子进程传递给 初始化. 使用这种机制,可以在不中断正在运行的应用程序的情况下更改窗口管理器。
即使在好的家庭中,事情也会时不时地出错。 在特殊情况下,进程可能会完成,而父进程可能不会等待该进程的完成。 这种未掩埋的过程称为 僵尸 的过程。
4.1.5.2. 结束进程
当一个进程正常结束时(它没有被杀死或意外中断),程序返回它的 退出状态 给父母。 此退出状态是程序返回的数字,提供程序执行的结果。 执行作业时返回信息的系统起源于编写 UNIX 的 C 编程语言。
然后返回代码可以由父级或在脚本中解释。 返回代码的值是特定于程序的。 该信息通常可以在指定程序的手册页中找到,例如 grep的 命令返回 -1 如果未找到匹配项,则可以打印“未找到文件”行上的消息。 另一个例子是 Bash 内置命令 true, 除了返回退出状态 0 之外什么都不做,这意味着成功。
4.1.5.3. 信号
进程结束是因为他们收到了一个信号。 您可以向一个进程发送多个信号。 使用 杀 命令向进程发送信号。 命令 杀 -l 显示信号列表。 大多数信号供系统内部使用,或供程序员编写代码时使用。 作为用户,您将需要以下信号:
表 4-2。 常见信号
信号名称 | 信号编号 | 意 |
目标期限 | 15 | 有条不紊地终止进程。 |
SIGINT | 2 | 中断进程。 一个进程可以忽略这个信号。 |
杀人狂 | 9 | 中断进程。 一个进程不能忽略这个信号。 |
签到 | 1 | 对于守护进程:重新读取配置文件。 |
您可以阅读有关在向进程发送信号时采取的默认操作的更多信息 男子 7 信号.
4.1.6. SUID 和 SGID
正如前一章所承诺的,我们现在将更详细地讨论特殊模式 SUID 和 SGID。 这些模式的存在是为了让普通用户能够执行他们通常无法执行的任务,因为在基于 UNIX 的系统上使用了严格的文件权限方案。 在理想情况下,尽可能少地使用特殊模式,因为它们包含安全风险。 Linux 开发人员通常会尽量避免使用它们。 Linux ps 例如,版本使用存储在 / proc中 文件系统,每个人都可以访问,从而避免将敏感的系统数据和资源暴露给公众。 在此之前,仍然在较旧的 UNIX 系统上, ps 程序需要访问文件,例如 / dev / mem 和 / dev / kmem,由于这些文件的权限和所有权而存在缺点:
丽塔:~> ls CRW-R----- | -l | /dev/*内存 1根 | em | 1, | 2 月 30 日 22:30 /dev/kmem |
CRW-R----- | 1根 | em | 1, | 1 月 30 日 22:30 /dev/mem |
与旧版本 ps,除非应用了特殊模式,否则无法以普通用户身份启动该程序。
虽然我们通常会尽量避免应用任何特殊模式,但有时还是需要使用 SUID。 一个例子是更改密码的机制。 当然,用户希望自己执行此操作,而不是由系统管理员设置密码。 众所周知,用户名和密码列在 / etc / passwd文件 文件,具有以下访问权限和所有者:
贝:~> ls -l /etc/密码
-rw-r--r-- 1 根根
1267 年 16 月 14 日 43:XNUMX /etc/passwd
贝:~> ls -l /etc/密码
-rw-r--r-- 1 根根
尽管如此,用户仍需要能够在此文件中更改自己的信息。 这是通过给 passwd文件
程序特殊权限:
米娅:~> 哪个密码
密码是 /usr/bin/passwd
米娅:~> 哪个密码
密码是 /usr/bin/passwd
米娅:~> ls -l /usr/bin/密码
-rs--x--x 1 根根
13476 7 月 06 日 03:XNUMX /usr/bin/passwd*
米娅:~> ls -l /usr/bin/密码
-rs--x--x 1 根根
当被调用时, passwd文件 命令将使用访问权限运行 根,从而使普通用户可以编辑系统管理员拥有的密码文件。
文件上的 SGID 模式不像 SUID 那样频繁出现,因为 SGID 经常涉及创建额外的组。 然而,在某些情况下,我们必须经历这个麻烦才能构建一个优雅的解决方案(不要太担心这个 - 必要的组通常在安装时创建)。 情况是这样的 写 和 墙 程序,用于向其他用户的终端(ttys)发送消息。 这 写 命令将消息写入单个用户,而 墙 写入所有连接的用户。
通常不允许向其他用户的终端或图形显示器发送文本。 为了绕过这个问题,创建了一个拥有所有终端设备的组。 当。。。的时候 写 和 墙 命令被授予 SGID 权限,命令将使用适用于该组的访问权限运行, TTY 在示例中。 由于该组对目标终端具有写入权限,因此无权以任何方式使用该终端的用户也可以向其发送消息。
在下面的例子中,用户 乔 首先找出他的通讯员连接在哪个终端上,使用 谁 命令。 然后他使用 写 命令。 还说明了对 写 程序和接收用户占用的终端上:很明显,除了用户所有者之外,其他人都没有对设备的权限,组所有者除外,可以对其进行写入。
乔:~> 哪个写
写是/usr/bin/write
乔:~> ls -l /usr/bin/写
-rwxr-sr-x 1 根 tty
8744 十二月 5 日 00:55 /usr/bin/write*
乔:~> 哪个写
写是/usr/bin/write
乔:~> ls -l /usr/bin/写
-rwxr-sr-x 1 根 tty
乔:~> 谁
珍妮 tty1
珍妮 分/1
珍妮 分/2
珍妮 分/3
乔 分/0
23 月 11 日 41:XNUMX
23 月 12 日 21:0 (:XNUMX)
23 月 12 日 22:0 (:XNUMX)
23 月 12 日 22:0 (:XNUMX)
20 月 10 日 13:XNUMX (lo.callhost.org)
乔:~> 谁
珍妮 tty1
珍妮 分/1
珍妮 分/2
珍妮 分/3
乔 分/0
乔:~> ls -l /dev/tty1
crw---w---- 1 珍妮 tty 4,
1 月 23 日 11:41 /dev/tty1
乔:~> ls -l /dev/tty1
crw---w---- 1 珍妮 tty 4,
乔:~> 写珍妮 tty1
嘿珍妮,我们一起吃午饭好吗?
^C
乔:~> 写珍妮 tty1
嘿珍妮,我们一起吃午饭好吗?
^C
用户 珍妮 在她的屏幕上看到这个:
副总经理 [电子邮件保护] ptys/1 12:36 ...嘿珍妮,我们一起吃午饭吗?
EOF
副总经理 [电子邮件保护] ptys/1 12:36 ...嘿珍妮,我们一起吃午饭吗?
EOF
终端收到消息后,可以使用 按Ctrl+L 组合键。 为了完全不接收消息(除了来自系统管理员的消息),请使用 MESG 命令。 要查看哪些已连接用户接受来自其他人的消息,请使用 谁 -w. 所有功能在每个命令的信息页面中都有详细说明。
组名可能会有所不同
组方案特定于分配。 其他发行版可能使用其他名称或其他解决方案。