内容


LPI 102 考试准备,主题 111

管理任务

初级管理(LPIC-1)主题 111

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: LPI 102 考试准备,主题 111

敬请期待该系列的后续内容。

此内容是该系列的一部分:LPI 102 考试准备,主题 111

敬请期待该系列的后续内容。

开始之前

本节解释这些教程讲授什么内容,以及如何从这些教程获得最大的收益。

关于本系列

Linux Professional Institute(LPI)对 Linux 系统管理员的认证分为三级:初级(也称为 “认证级别 1”)、中级(也称为 “认证级别 2”)和高级(也称为 “认证级别 3”)。要获得认证级别 1,您必须通过 101 和 102 考试;要获得认证级别 2,您必须通过 201 和 202 考试。要获得认证级别 3,您必须已经获得中级认证,并通过 301 考试(“core”)。在高级认证中,可能还要通过其他专业考试。

developerWorks 提供教程来帮助您准备初级和中级认证的 4 门考试。每门考试包含几个主题,每个主题在 developerWorks 上都有一个对应的自学教程。对于 LPI 102 考试,有以下 9 个主题和对应的 developerWorks 教程:

表 1. LPI 102 考试:教程和主题
LPI 102 考试主题developerWorks 教程教程摘要
主题 105LPI 102 考试准备:
内核
学习如何安装和维护 Linux 内核和内核模块。
主题 106LPI 102 考试准备:
引导、初始化、关机和运行级别
学习如何引导系统、设置内核参数以及关闭或重新引导系统。
主题 107LPI 102 考试准备:
打印
学习如何在 Linux 系统上管理打印机、打印队列和用户的打印作业。
主题 108LPI 102 考试准备:
文档
学习如何使用并管理本地文档、在互联网上查找文档以及使用自动化登录消息来通知用户系统事件的发生。
主题 109LPI 102 考试准备:
shell、脚本、编程和编译
学习如何对自己的 shell 环境进行定制以满足用户需求、如何为经常使用的命令序列编写 Bash 函数、如何编写简单的新脚本、使用 shell 语法进行循环和测试,以及如何对现有脚本进行定制。
主题 111LPI 102 考试准备:
管理任务
(本教程)。学习如何管理用户和组帐户、对用户和系统环境进行调优、配置和使用系统日志文件、通过调度作业在以后自动执行系统管理任务、对系统进行备份和维护系统时间。参见下面详细的 目标
主题 112LPI 102 考试准备:
网络基础
敬请期待!
主题 113LPI 102 考试准备:
网络服务
敬请期待!
主题 114LPI 102 考试准备:
安全性
敬请期待!

要想通过考试 101 和 102(并获得认证级别 1),您应该能够:

  • 在 Linux 命令行上进行操作。
  • 执行简单的维护作业:帮助用户、向更大的系统中添加用户、备份和恢复、关机和重新引导。
  • 安装和配置工作站(包括 X)并将它连接到 LAN,或者通过调制解调器将单独的 PC 连接到互联网。

要想继续准备认证级别 1,请参考 针对 LPI 101 和 102 考试的 developerWorks 教程 以及 全套 developerWorks LPI 教程

Linux Professional Institute 不为任何第三方考试准备资料或做技术担保。详情请联系 info@lpi.org

关于本教程

欢迎阅读 “管理任务”,这是针对 LPI 102 考试而设计的 9 篇教程中的第 6 篇。在本教程中,您将学习如何管理用户和组、设置用户配置文件和环境、使用日志文件、调度作业、备份数据和维护系统时间。

本教程是按照这个主题的 LPI 目标组织的。大致来说,权值越高的学习目标,在考试中出的题就越多。

表 2. 管理任务:本教程中涉及的考试目标
LPI 考试目标目标权值目标摘要
1.111.1
用户和组帐户
权值 4添加、删除、终止和修改用户帐户。管理密码和组数据库中的用户和组信息,包括影子数据库。创建和管理用于特殊用途的和受限制的帐户。
1.111.2
对用户和系统环境进行调优
权值 3修改全局和用户配置文件。设置环境变量并为新用户帐户维护框架目录。设置命令搜索路径。
1.111.3
配置和使用系统日志文件来满足管理和安全需求
权值 3配置和管理系统日志,包括日志记录的信息的类型和级别。通过扫描和监视日志文件了解值得注意的活动,调查发现的问题。轮替日志文件并进行存档。
1.111.4
通过调度作业在以后自动执行系统管理任务
权值 4使用 cronanacron 命令以一定的时间间隔运行作业,使用 at 命令在指定的时间运行作业。
1.111.5
维护一个有效的数据备份策略
权值 3制定备份策略,并将文件系统自动地备份到各种媒体。
1.111.6
维护系统时间
权值 4维护系统时间和时区,通过 NTP 进行时钟同步。将 BIOS 时钟设置为适当的 UTC 时间并配置 NTP,包括纠正时钟漂移。

先决条件

要想从本教程获得最大的收益,您应该具备 Linux 的基础知识并且拥有一个可用于实践本教程中的命令的 Linux 系统。

本教程依赖于这个 LPI 考试系列前面的教程介绍的内容,所以您可能需要先参考 针对考试 101 的教程。您尤其应该熟悉 “LPI 101 考试准备(主题 104):设备、Linux 文件系统和文件系统层次标准” 教程,其中讨论了用户、组和文件权限的基本概念。

不同的程序版本可能会导致不同格式的输出,所以您在进行实践时获得的结果可能会与本教程中的清单和图有所不同。

用户和组帐户

本节介绍初级管理(LPIC-1)考试 102 的 1.111.1 主题的内容。这个主题的权值为 4。

在本节中,我们将学习如何:

  • 添加、修改和删除用户和组
  • 终止和修改用户帐户
  • 管理密码数据库和组数据库中的用户和组信息
  • 使用正确的工具管理影子密码数据库和组数据库
  • 创建和管理受限制的和用于特殊用途的帐户

正如在 “LPI 101 考试准备(主题 104):设备、Linux 文件系统和文件系统层次标准” 中学到的,Linux 是一种多用户系统,Linux 上的每个用户属于一个 组,还可能属于其他组。在 Linux 中,文件的所有权与用户 id 和组密切相关。注意,可以作为一个用户登录,然后使用 susudo -s 变成另一个用户,然后可以使用 whoami 命令检查当前的有效 id,使用 groups 命令了解当前用户所属的组。在本节中,学习如何创建、删除和管理用户和组。还要了解 /etc 中的文件,这个目录中存储用户和组信息。

添加和删除用户和组

使用 useradd 命令在 Linux 系统中添加用户,使用 userdel 命令删除用户。与此相似,分别使用 groupaddgroupdel 命令添加和删除组。

添加用户或组

现代的 Linux 桌面往往为用户和组管理提供了图形界面。常常可以通过用于系统管理的菜单项访问这些图形界面。这些界面的差异相当大,所以您系统上的界面可能与这里的示例不一样,但是底层概念和命令是相似的。

首先,以图形化方式在 Fedora Core 5 系统中添加一个用户,然后查看底层命令。对于使用 GNOME 桌面的 Fedora Core 5,使用 System > Administration > Users and Groups,然后单击 Add User 按钮。

图 1 显示 User Manager 面板和 Create New User 面板,其中显示了新用户 ‘john’ 的基本信息。已经输入了用户的完整姓名(John Doe)和密码。面板指定默认的登录 shell 为 /bin/bash。在 Fedora 系统上,默认行为是创建一个与这个用户同名(在这个示例中是 ‘john’)的新组和主目录 /home/john。

图 1. 添加用户
添加用户
添加用户

清单 1 显示如何使用 id 命令显示这个新用户的基本信息。可以看到,john 的用户编号是 503,他与 john 组(组编号为 503)相关联。这是 john 所属的惟一一个组。

清单 1. 显示用户 id 信息
[root@pinguino ~]# id john
uid=503(john) gid=503(john) groups=503(john)

要想从命令行完成同样的任务,应该使用 groupadduseradd 创建组和用户,然后使用 passwd 命令为新创建的用户设置密码。这些命令都需要根权限。清单 2 使用这些命令添加另一个用户 jane。

清单 2. 添加用户 jane
[root@pinguino ~]# groupadd jane
[root@pinguino ~]# useradd -c "Jane Doe" -g jane -m jane
[root@pinguino ~]# passwd jane
Changing password for user jane.
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
[root@pinguino ~]# id jane
uid=504(jane) gid=504(jane) groups=504(jane)
[root@pinguino ~]# ls -ld /home/jane
drwx------ 3 jane jane 4096 Jun 25 18:22 /home/jane

在这两个示例中,用户 id 和组 id 的值都大于 500。请注意,一些比较新的系统的用户 id 从 1000 开始编号,而不是从 500 开始。这些值通常表示普通用户,500(对于从 1000 开始普通用户编号的系统,是 1000)以下的值是为系统用户 保留的。本节后面将讨论 系统用户。实际的分界点是在 /etc/login.defs 中作为 UID_MINGID_MIN 设置的。

在上面的清单 2 中,groupadd 命令接受一个参数 jane,这是要添加的组的名称。组名必须以小写字母或下划线开头,通常只包含小写字母、下划线和连字符或破折号。可以指定的选项见表 3。

表 3. groupadd 的选项
选项用途
-f如果这个组已经存在,那么以成功状态退出。这对于脚本编程很方便,这样就不需要在尝试创建一个组之前检查它是否存在。
-g手工指定组 id。默认行为是使用大于等于 GID_MIN 并大于现有的任何组 id 的最小值。组 id 通常是惟一的,而且必须是非负的。
-o允许组具有非惟一的 id。
-K可以用来覆盖来自 /etc/login.defs 的默认设置。

在上面的清单 2 中,useradd 命令接受一个参数 jane,这是要添加的用户的名称,还指定了 -c-g-m 选项。useradd 命令的常用选项见表 4。

表 4. useradd 的选项
选项用途
-b
--base-dir
创建用户主目录的默认基目录。这常常是 /home,用户的主目录是 /home/$USER。
-c
--comment
描述 id 的文本字符串,比如用户的完整姓名。
-d
--home
为主目录指定目录名。
-e
--expiredate
帐户将过期或禁用的日期,采用的形式是 YYYY-MM_DD。
-g
--gid
用户的初始登录组的名称或编号。这个组必须已经存在,所以在清单 2 中先创建 jane 组,然后再创建 jane 用户。
-G
--groups
用户所属的其他组的列表(以逗号分隔)。
-K可以用来覆盖来自 /etc/login.defs 的默认设置。
-m
--create-home
如果用户的主目录不存在,就创建它。将 /etc/skel 中的骨架文件和所有目录复制到主目录。
-o
--non-unique
允许用户具有非惟一的 id。
-p
--password
加密的密码。如果没有指定密码,默认行为是禁用帐户。通常会在后续步骤中使用 passwd 命令,而不是生成加密的密码并在 useradd 命令中指定它。
-s
--shell
如果用户的登录 shell 不是默认的登录 shell,那么可以用这个选项指定用户的登录 shell 的名称。
-u
--uid
非负的数字用户 id;如果没有指定 -o 选项,那么用户 id 必须是惟一的。默认行为是使用大于等于 UID_MIN 并大于现有的任何用户 id 的最小值。

注意:

  1. 一些系统(包括 Fedora 和 Red Hat 发行版)对创建用户命令提供了扩展。例如,默认的 Fedora 和 Red Hat 行为是为一个用户创建一个新组,可以在 useradd 命令中使用 -n 选项来禁用这个功能。应该了解这些系统差异,如果有疑问,应该参考系统上的手册页。
  2. 在 SUSE 系统上,使用 YaST 或 YaST2 访问用户和组管理图形界面。
  3. 图形界面可能会执行其他任务,比如在 /var/spool/mail 中创建用户的邮件文件。

删除用户或组

与添加用户或组相比,删除用户或组要简单得多,因为选项更少。实际上,用来删除组的 groupdel 命令只需要组名;它没有选项。不能删除任何用户的主组。如果使用图形界面删除用户或组,其功能与这里显示的命令非常相似。

使用 userdel 命令删除用户。-r--remove 选项请求同时删除用户的主目录以及其中包含的任何内容,还删除用户的邮件 spool。如果在 /etc/login.defs 中还设置了 USERGROUPS_ENAB 为 yes,那么在删除用户时,还会删除与用户同名的组,但这个组必须不是另一个用户的主组。

在清单 3 中可以看到一个删除组的示例,在这里有多个用户共享同一个主组。之前已经在系统中添加了另一个用户 jane2,他的组与 jane 相同。

清单 3. 删除用户和组
root@pinguino:~# groupdel jane
groupdel: cannot remove user's primary group.
root@pinguino:~# userdel -r jane
userdel: Cannot remove group jane which is a primary group for another user.
root@pinguino:~# userdel -r jane2
root@pinguino:~# groupdel jane

注意:

  1. 有一个 userdel 选项 -f--force,可以使用它同时删除用户和他们的组。这个选项很危险,只应该作为最后的手段。执行此操作之前,请仔细阅读手册页。
  2. 注意,如果删除用户或组,而且文件系统上有属于这个用户或组的文件,那么这些文件不会自动地删除或分配给另一个用户或组。

终止和修改帐户

您现在可以创建或删除用户 id 或组,还可能需要修改它们。

修改用户帐户

假设用户 john 希望用 tcsh shell 作为默认 shell。常常可以在图形界面中找到编辑用户(或组)的方法,或者查看对象属性的方法。图 2 是 Fedora Core 5 系统上用户 john 的属性对话框。

图 2. 修改用户帐户
修改用户帐户

在命令行上可以使用 usermod 命令修改用户帐户。可以使用 useradd 的大多数选项,但是不能为这个用户创建或填充新的主目录。如果需要修改用户名,那么指定 -l--login 选项并加上新名称。可能希望修改主目录名称来匹配用户 id。还可能需要修改其他项目的名称,比如电子邮件 spool 文件。如果修改登录 shell,那么可能需要修改一些相关联的配置文件。清单 4 将用户 john 改为 john2,将 /bin/tcsh 设置为默认 shell,并将主目录重命名为 /home/john2。

清单 4. 修改用户
[root@pinguino ~]# usermod -l john2 -s /bin/tcsh -d /home/john2 john
[root@pinguino ~]# ls -d ~john2
ls: /home/john2: No such file or directory
[root@pinguino ~]# mv /home/john /home/john2
[root@pinguino ~]# ls -d ~john2
/home/john2

注意:

  1. 如果需要修改用户的其他组,那么必须指定其他组的完整列表。没有命令只为用户添加或删除一个组。
  2. 如果一个用户已经登录,或者他有正在运行的进程,那么对修改他的名称或 id 有一些限制。详情请查阅手册页。
  3. 如果修改一个用户的编号,可能希望修改他拥有的文件和目录来匹配这个新编号。

修改组

使用 groupmod 修改组信息。用 -g 选项修改组编号,用 -n 选项修改名称。

清单 5. 修改组名称
[root@pinguino ~]# ls -ld ~john2
drwx------ 3 john2 john 4096 Jun 26 18:29 /home/john2
[root@pinguino ~]# groupmod -n john2 john
[root@pinguino ~]# ls -ld ~john2
drwx------ 3 john2 john2 4096 Jun 26 18:29 /home/john2

在清单 5 中,当使用 groupmod 修改组名称时,john2 的组目录的组名称自动地改变了。觉得奇怪吗?因为组在文件系统索引节中由它们的编号表示,而不是由名称表示。但是,如果修改组的编号,那么应该更新以这个组作为主组的所有用户,还可能希望更新属于这个组的文件和目录来匹配新编号(采用上面介绍的修改用户编号的方法)。清单 6 将用户 john2 的组编号改为 505,更新用户帐户,并对 /home 文件系统中受影响的所有文件做适当的修改。如果可能的话,您也许希望对用户和组重新编号。

清单 6. 修改组编号
[root@pinguino ~]# groupmod -g 505 john2
[root@pinguino ~]# ls -ld ~john2
drwx------ 3 john2 503 4096 Jun 26 18:29 /home/john2
[root@pinguino ~]# id john2
uid=503(john2) gid=503 groups=503
[root@pinguino ~]# usermod -g john2 john2
[root@pinguino ~]# id john2
uid=503(john2) gid=505(john2) groups=505(john2)
[root@pinguino ~]# ls -ld ~john2
drwx------ 3 john2 503 4096 Jun 26 18:29 /home/john2
[root@pinguino ~]# find /home -gid 503 -exec chgrp john2 {} \;
[root@pinguino ~]# ls -ld ~john2
drwx------ 3 john2 john2 4096 Jun 26 18:29 /home/john2

用户和组密码

您已经看到了用来修改用户密码的 passwd 命令。密码是(或应该是)用户惟一的,可以由用户修改。根用户可以修改任何用户的密码。

组也可以有密码,使用 gpasswd 命令设置它们。如果用户知道组密码,他们就能够用 newgrp 命令临时加入一个组。当然,让许多人知道一个密码是不安全的,所以必须权衡用 usermod 将用户加入组的优点,以及让太多人知道组密码的安全风险。

终止或锁定帐户

如果需要禁止一个用户登录,那么可以使用 usermod 命令的 -L 选项终止(suspend)锁定(lock)帐户。使用 -U 选项给帐户解锁(unlock)。清单 7 显示如何锁定 john2 帐户,以及在 john2 试图登录系统时发生的情况。注意,当 john2 帐户解锁时,会恢复相同的密码。

清单 7. 锁定帐户
[root@pinguino ~]# usermod -L john2
[root@pinguino ~]# ssh john2@pinguino
john2@pinguino's password:
Permission denied, please try again.

图 2 中,对话框上有几个选项卡显示其他用户属性。我们简要提到了如何使用 passwd 命令设置用户密码,但是这个命令和 usermod 命令都可以执行与用户帐户相关的许多任务,它们的作用与 chage 命令相似。表 5 列出了一部分选项。关于这些和其他选项的更多细节,请参考手册页。

表 5. 修改用户帐户的命令和选项
命令的选项用途
UsermodPasswdChage
-L-lN/A锁定或终止帐户。
-U-uN/A对帐户解锁。
N/A-dN/A将帐户设置为无密码,从而禁用帐户。
-e-f-E为帐户设置过期日期。
N/A-n-m以天为单位的最小密码生命周期。
N/A-x-M以天为单位的最大密码生命周期。
N/A-w-W在必须修改密码之前提前发出警告的天数。
-f-i-I密码过期之后,直到禁用帐户之前的天数。
N/A-S-l输出关于当前帐户状态的简短消息。

管理用户和组数据库

用户和组信息的主要存储库是 /etc 中的 4 个文件。

/etc/passwd
这是密码 文件,包含关于用户的基本信息
/etc/shadow
这是影子密码 文件,包含加密的密码
/etc/group
这是 文件,包含组的基本信息以及哪些用户属于哪些组
/etc/gshadow
这是影子组 文件,包含加密的组密码

本文前面介绍的命令会更新这些文件;在讨论这些文件之后,您还会看到处理它们的更多命令。这些文件都是纯文本文件。一般情况下,不应该直接编辑它们。应该使用工具更新它们,从而正确地锁定它们并保持同步。

您会注意到,passwd 和 group 文件都阴影化 了。这是为了保障安全。passwd 和 group 文件本身必须是广泛可读的,但是加密的密码不应该是广泛可读的。因此,影子文件包含加密的密码,只有根用户能够读取这些文件。suid 程序提供必要的身份验证访问;suid 程序具有根权限,但是任何人都可以运行它。确保为您的系统正确地设置权限。清单 8 给出一个示例。

清单 8. 用户和组数据库权限
[ian@pinguino ~]$ ls -l /etc/passwd /etc/shadow /etc/group /etc/gshadow
-rw-r--r-- 1 root root  701 Jun 26 19:04 /etc/group
-r-------- 1 root root  580 Jun 26 19:04 /etc/gshadow
-rw-r--r-- 1 root root 1939 Jun 26 19:43 /etc/passwd
-r-------- 1 root root 1324 Jun 26 19:50 /etc/shadow

注意: 尽管从技术上说可以不使用影子密码和影子组文件,但是几乎从不这样做,也不建议这样做。

/etc/passwd 文件

/etc/passwd 文件对于系统中的每个用户包含一行记录。清单 9 给出了一些示例行。

清单 9. /etc/password 条目
root:x:0:0:root:/root:/bin/bash
jane:x:504:504:Jane Doe:/home/jane:/bin/bash
john2:x:503:505:John Doe:/home/john2:/bin/tcsh

每行包含几个由冒号(:)分隔的字段,见表 6。

表 6. /etc/passwd 中的字段
字段用途
Username用来登录系统的用户名。例如,john2。
Password加密的密码。在使用影子密码时,它包含一个 x 字符。
User id
(UID)
在系统中用来表示这个用户名的编号。例如,用户 john2 的编号是 503。
Group id
(GID)
在系统中用来表示这个用户的主组的编号。例如,用户 john2 的组编号是 505。
Comment
(GECOS)
一个用来描述用户的可选字段。例如,“John Doe”。这个字段可以包含多个逗号分隔的条目。它还由 finger 等程序使用。GECOS 这个名称是由于历史原因形成的。详情见 man 5 passwd
Home用户主目录的绝对路径。例如,/home/john2。
Shell当用户登录系统时自动启动的程序。这常常是一个交互式 shell,比如 /bin/bash 或 /bin/tcsh,但可能是任何程序,不一定是交互式的 shell。

/etc/group 文件

/etc/group 文件对于系统中的每个组包含一行记录。清单 10 给出了一些示例行。

清单 10. /etc/group 条目
root:x:0:root
jane:x:504:john2
john2:x:505:

每行包含四个由冒号(:)分隔的字段,见表 7。

表 7. /etc/group 中的字段
字段用途
Groupname这个组的名称。例如,john2。
Password加密的密码。在使用影子密码时,它包含一个 x 字符。
Group id
(GID)
在系统中用来表示这个组的编号。例如,组 john2 的编号是 505。
Members逗号分隔的组成员列表,但是不包括以这个组作为主组的成员。

影子文件

应该只有根用户能够读取 /etc/shadow 文件。它包含加密的密码,以及密码和帐户的过期信息。关于其中的字段的信息,参见手册页(man 5 shadow)。密码可以使用 DES 加密,但是常常使用 MD5 加密。DES 算法使用用户密码的前 8 个字符的低 7 位作为 56 位的密钥,而 MD5 算法使用整个密码。在这两种算法中,都对密码做 salt 处理,所以两个在其他方面相同的密码不会生成相同的加密值。清单 11 演示如何为用户 jane 和 john2 设置相同的密码,然后显示在 /etc/shadow 中生成的 MD5 加密密码。

清单 11. /etc/shadow 中的密码
[root@pinguino ~]# echo lpic1111 |passwd jane --stdin
Changing password for user jane.
passwd: all authentication tokens updated successfully.
[root@pinguino ~]# echo lpic1111 |passwd john2 --stdin
Changing password for user john2.
passwd: all authentication tokens updated successfully.
[root@pinguino ~]# grep "^j" /etc/shadow
jane:$1$eG0/KGQY$ZJl.ltYtVw0sv.C5OrqUu/:13691:0:99999:7:::
john2:$1$grkxo6ie$J2muvoTpwo3dZAYYTDYNu.:13691:0:180:7:29::

输出开头的 $1$ 表示一个 MD5 密码。下面是 salt 值(直到下一个 $ 符号为止),它是一个最多 8 字符的长度可变的字段。余下的 22 字符的字符串是加密的密码。

操作用户和组的工具

您已经看到了几个操作用户帐户和组文件及其影子文件的命令。下面学习:

  • 组管理员
  • 编辑密码和组文件的命令
  • 转换程序

组管理员

在某些情况下,可能希望让根用户之外的用户能够管理一个或多个组,比如添加或删除组成员。清单 12 展示了根用户将用户 jane 设置为组 john2 的管理员,然后 jane 将用户 ian 添加为组成员。

清单 12. 添加组管理员和成员
[root@pinguino ~]# gpasswd -A jane john2
[root@pinguino ~]# su - jane
[jane@pinguino ~]$ gpasswd -a ian john2
Adding user ian to group john2
[jane@pinguino ~]$ id ian;id jane
uid=500(ian) gid=500(ian) groups=500(ian),505(john2)
uid=504(jane) gid=504(jane) groups=504(jane)

您可能会吃惊地发现,尽管 jane 是组 john2 的管理员,但她不是这个组的成员。/etc/gshadow 文件的结构可以解释这一现象的原因。/etc/gshadow 文件为每个条目包含四个字段,见表 8。注意,第三个字段是逗号分隔的组管理员列表。

表 8. /etc/gshadow 中的字段
字段用途
Groupname这个组的名称。例如,john2。
Password如果这个组有密码,这个字段就用来保存加密的密码。如果没有密码,在这里可能会看到 ‘x’、‘!’ 或 ‘!!’。
Admins逗号分隔的组管理员列表。
Members逗号分隔的组成员列表。

可以看到,管理员列表和成员列表是两个不同的字段。gpasswd-A 选项允许根用户添加组管理员,-M 选项允许根用户添加组成员。-a(注意,是小写的)选项允许管理员添加组成员,-d 选项允许管理员删除组成员。其他选项可以删除组密码。细节见手册页。

编辑密码和组文件的命令

尽管不属于 LPI 学习目标,但是还应该知道 vipw 命令可以安全地编辑 /etc/passwd,vigr 命令可以安全地编辑 /etc/group。在使用 vi 编辑器进行修改时,这些命令会锁定相关文件。如果修改 /etc/passwd,那么 vipw 会询问是否也需要更新 /etc/shadow。同样,如果使用 vigr 更新 /etc/group,就会询问是否更新 /etc/gshadow。如果需要删除组管理员,就需要使用 vigr,因为 gpasswd 只能添加管理员。

转换程序

还有四个没有在 LPI 学习目标中列出的相关命令。它们是 pwconvpwunconvgrpconvgrpunconv。它们用来在影子和非影子密码和组文件之间进行转换。您可能不会用到它们,但是应该知道有这些命令存在。细节参见手册页。

受限制的和特殊用途的帐户

按照惯例,系统用户常常具有小于 100 的 id,根用户的 id 是 0。普通用户的自动编号是从 /etc/login.defs 中设置的 UID_MIN 值开始的,这个值常常设置为 500 或 1000。

除了普通用户帐户和根帐户之外,系统上常常有几个特殊用途的帐户,它们用于 FTP、SSH、邮件、新闻等守护进程。清单 13 显示 /etc/passwd 中一些特殊用途帐户的记录。

清单 13. 受限制的和特殊用途的帐户
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin

这样的帐户常常控制着文件,但是不应该通过普通的登录访问它们。因此,它们的登录 shell 常常设置为 /sbin/nologin 或 /bin/false,所以登录尝试会失败。

环境调优

本节介绍初级管理(LPIC-1)考试 102 的 1.111.2 主题的内容。这个主题的权值为 3。

在本节中,学习如何对用户环境进行调优,包括以下任务:

  • 设置和取消环境变量
  • 为新用户帐户维护框架目录
  • 设置命令搜索路径

设置和取消环境变量

在创建新用户时,常常根据自己的需要对许多变量进行初始化。这些变量常常是在为新用户提供的配置文件中设置的,比如 .bash_profile 和 .bashrc,也可以在系统范围的配置文件 /etc/profile 和 /etc/bashrc 中设置。清单 14 演示如何在 Ubuntu 7.04 系统上的 /etc/profile 中设置 PS1 系统提示。第一个 if 语句检查是否设置了 PS1 变量(这表示一个交互式 shell),因为非交互式 shell 不需要提示。第二个 if 语句检查是否设置了 BASH 环境变量。如果设置了,那么设置一个复杂的提示和源 /etc/bash.bashrc(注意点号)。如果没有设置 BASH 变量,对根进行检查(id=0),并将提示相应地设置为 # 或 $。

清单 14. 设置环境变量
if [ "$PS1" ]; then
  if [ "$BASH" ]; then
    PS1='\u@\h:\w\$ '
    if [ -f /etc/bash.bashrc ]; then
        . /etc/bash.bashrc
    fi
  else
    if [ "`id -u`" -eq 0 ]; then
      PS1='# '
    else
      PS1='$ '
    fi
  fi
fi

教程 “LPI 102 考试准备:shell、脚本、编程和编译” 详细描述了设置和取消环境变量所用的命令,还介绍了如何以及何时使用各个配置文件。

在为用户定制环境时,要注意两个重要问题:

  1. 系统只在用户登录时读取 /etc/profile,所以在创建每个新 shell 时并不执行它。
  2. 新 shell 并不继承函数和别名。因此,常常要根据自己的需要在 /etc/bashrc 中或用户自己的配置文件中设置环境变量。

除了系统配置文件 /etc/profile 和 /etc/bashrc 之外,Linux Standard Base(LSB)还指定其他脚本可以放在 /etc/profile.d 目录中。当创建交互式登录 shell 时,会执行这些脚本。它们提供了将不同程序的定制设置分隔开的简便方法。清单 15 给出一个示例。

清单 15. Fedora 7 上的 /etc/profile.d/vim.sh
[if [ -n "$BASH_VERSION" -o -n "$KSH_VERSION" -o -n "$ZSH_VERSION" ]; then
  [ -x //usr/bin/id ] || return
  [ `//usr/bin/id -u` -le 100 ] && return
  # for bash and zsh, only if no alias is already set
  alias vi >/dev/null 2>&1 || alias vi=vim
fi

请记住,应该常常对配置文件中设置的变量执行 export;否则,它们不会对新 shell 中运行的命令生效。

为新用户维护框架目录

在 “添加和删除用户和组” 一节中,您学习了如何为用户创建和填充新的主目录。这个新目录的内容来自以 /etc/skel 为根的子目录树。清单 16 显示 Fedora 7 系统上这个子树中的文件。注意,大多数文件以点号开头,所以需要用 -a 选项才能在目录列表中列出它们。-R 选项递归地列出子目录,-L 选项会显示任何符号链接。

清单 16. Fedora 7 上的 /etc/skel
[ian@lyrebird ~]$ ls -aRL /etc/skel
/etc/skel:
.  ..  .bash_logout  .bash_profile  .bashrc  .emacs  .xemacs

/etc/skel/.xemacs:
.  ..  init.el

除了 Bash shell 所需的 .bash_logout、.bash_profile 和 .bashrc 之外,这个示例还包含 emacs 和 xemacs 编辑器的配置文件信息。如果需要了解各个配置文件的功能,请参考教程 “LPI 102 考试准备:shell、脚本、编程和编译

清单 17 显示以上系统中的 /etc/skel/.bashrc。在不同的版本或不同的发行版上,这个文件可能不一样,但是它说明了默认用户设置是如何建立的。

清单 17. Fedora 7 上的 /etc/skel/.bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific aliases and functions

可以看到,首先执行全局 /etc/bashrc,然后可以添加用户特有的指令。清单 18 给出 /etc/bashrc 中的一部分,它执行 /etc/profile.d 中的 .sh 脚本。

清单 18. 执行 /etc/profile.d 中的 .sh 脚本
        for i in /etc/profile.d/*.sh; do
                if [ -r "$i" ]; then
                        . $i
        fi
        done
        unset i

注意,在循环之后取消了变量 i。

设置命令搜索路径

默认的配置文件常常包含本地功能或安装的产品的 PATH 变量。可以在 /etc/skel 中的骨架文件中设置这些变量,或者通过修改 /etc/profile 和 /etc/bashrc 或在 /etc/profile.d 中创建文件来设置这些变量。如果修改了系统文件,那么在任何系统更新之后,都要检查您的修改是否保持不变。清单 19 演示如何在现有的 PATH 之前或之后添加一个新目录 /opt/productxyz/bin。

清单 19. 添加路径目录
PATH="$PATH${PATH:+:}/opt/productxyz/bin"
PATH="/opt/productxyz/bin${PATH:+:}$PATH"

表达式 ${PATH:+:} 不是必需的;如果 PATH 变量未设置或者为空,它就插入一个路径分隔符(冒号)。

系统日志文件

本节介绍初级管理(LPIC-1)考试 102 的 1.111.3 主题的内容。这个主题的权值为 3。

在本节中,学习如何配置和管理系统日志,包括以下任务:

  • 管理日志记录的信息的类型和级别
  • 自动地轮替日志文件并进行存档
  • 扫描日志文件来了解值得注意的活动
  • 监视日志文件
  • 调查日志文件中报告的问题

管理日志记录的信息的类型和级别

Linux 系统上的系统日志功能可以记录系统日志和捕捉内核消息。日志记录可以在本地系统上执行,也可以发送到远程系统。可以通过 /etc/syslog.conf 配置文件细致地控制日志记录的级别。日志记录由 syslogd 守护进程执行,这个守护进程通常通过 /dev/log 套接字接收输入,见清单 20。

清单 20. /dev/log 是一个套接字
ian@pinguino:~$ ls -l /dev/log
srw-rw-rw- 1 root root 0 2007-07-05 15:42 /dev/log

对于本地日志记录,主要文件常常是 /var/log/messages,但是在大多数系统中还使用其他许多文件,而且可以对这些文件进行定制。例如,可能希望对来自邮件系统的消息使用单独日志文件。

syslog.conf 配置文件

syslog.conf 文件是 syslogd 守护进程的主要配置文件。日志记录基于设施和优先级两方面。定义的设施是 auth(或 security)、authpriv、cron、daemon、ftp、kern、lpr、mail、mark、news、syslog、user、uucp 以及 local0 到 local7。应该使用关键字 auth 而不是 security,关键字 mark 只供内部使用。

优先级如下(按升序排列):

  1. debug
  2. info
  3. notice
  4. warning(或 warn)
  5. err(或 error)
  6. crit
  7. alert
  8. emerg(或 panic)

括号中的关键字(warn、error 和 panic)现在已经废弃了。

syslog.conf 中的条目指定日志记录规则。每个规则有一个选择符字段和一个动作字段,它们由一个或多个空格或制表符分隔。选择符字段标识应用这个规则的设施和优先级,动作字段标识对于这个设施和优先级应该采用的日志记录动作。默认的行为是执行指定级别和所有更高级别的动作,但是也可以将日志记录限制在特定的级别。每个选择符由设施和优先级组成(由点号分隔)。对于一个给定的动作,可以指定多个设施,它们之间由逗号分隔。对于一个给定的动作,可以指定多个设施/优先级对,它们之间由分号分隔。清单 21 显示一个简单的 syslog.conf 示例。

清单 21. syslog.conf 示例
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.*                                                 /dev/console

# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none                /var/log/messages

# The authpriv file has restricted access.
authpriv.*                                              /var/log/secure

# Log all the mail messages in one place.
mail.*                                                  -/var/log/maillog

# Log cron stuff
cron.*                                                  /var/log/cron

# Everybody gets emergency messages
*.emerg                                                 *

# Save news errors of level crit and higher in a special file.
uucp,news.crit                                          /var/log/spooler

# Save boot messages also to boot.log
local7.*                                                /var/log/boot.log

注意:

  • 与许多配置文件一样,以 # 开头的行和空行被忽略。
  • 可以使用 * 表示所有设施或所有优先级。
  • 特殊的优先级关键字 none 表示对于这个设施不应该用这个动作记录日志。
  • 文件名前面的连字符(比如这个示例中的 -/var/log/maillog)表示日志文件不应该在每次写操作之后进行同步。如果这么做,在系统崩溃时可能会丢失信息,但是对性能有好处。

动作常常被称为 “日志文件”,但是它们不一定是真实的文件。表 9 描述了可能的日志文件。

表 9. syslog.conf 中的动作
动作用途
常规文件指定完整的路径名,以斜线(/)开头。如果在前面加上连字符(-),就会省略每次日志输入之后的文件同步。如果发生系统崩溃,这可能会导致信息丢失,但是可以提高性能。
命名管道可以使用 fifo 或命名管道作为日志消息的目标,设置方法是在文件名前面加一个管道符(|)。在启动(或重新启动)syslogd 之前必须使用 mkfifo 命令创建 fifo。有时候使用 fifo 进行调试。
终端和控制台一个终端,比如 /dev/console。
远程机器要想将消息转发给另一个主机,应该在主机名前面加一个 at(@)符号。注意,接收主机并不向外转发消息。
用户的列表要接收消息的用户的逗号分隔的列表(要求用户已经登录)。这里常常包含根用户。
登录的每个用户指定星号(*),就会使用 wall 命令通知登录的每个用户。

可以在优先级前面加上 !,这表示这个动作不应该应用于这个级别和更高级别。还可以在前面加上 =,这表示这个规则只应用于这个级别;加 != 表示规则应用于除这个级别之外的所有级别。清单 22 给出一些示例,syslog.conf 的手册页提供了更多示例。

清单 22. syslog.conf 示例
# Store all kernel messages in /var/log/kernel.
# Send critical and higher ones to remote host pinguino and to the console
# Finally, Send info, notice and warning messages to /var/log/kernel-info
#
kern.*                       /var/log/kernel
kern.crit                    @pinguino
kern.crit                    /dev/console
kern.info;kern.!err          /var/log/kernel-info

# Store all mail messages except info priority in /var/log/mail. 
mail.*;mail.!=info           /var/log/mail

自动地轮替日志文件并进行存档

由于日志消息的数量可能很大,所以需要能够控制日志文件的大小。这需要使用 logrotate 命令,这个命令通常作为 cron 作业运行。本章后面的 调度作业 一节将讨论 cron 作业。logrotate 命令的运行原理是,定期备份日志文件并开始一个新的日志。保留几代备份,当一个日志到达最后一代时,可以将它存档。例如,可以将它发送给存档用户。

使用 /etc/logrotate.conf 配置文件指定日志应该如何轮替和存档。可以为不同的日志文件指定不同的频率,比如每天、每周或每月,还可以控制代的数量以及何时或是否将副本发送给存档用户。清单 23 给出一个 /etc/logrotate.conf 文件示例。

清单 23. /etc/logrotate.conf 示例
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp, or btmp -- we'll rotate them here
/var/log/wtmp {
    missingok
    monthly
    create 0664 root utmp
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0664 root utmp
    rotate 1
}

# system-specific logs may be configured here

logrotate.conf 文件的开头是全局选项。这些是默认设置,如果在别的地方没有指定更特定的设置,就使用这些默认设置。在这个示例中,日志文件每周轮替一次,并保留 4 周的备份。在日志文件轮替时,自动创建一个新的日志文件来替代旧文件。注意,logrotate.conf 文件可以包含来自其他文件的设置。在这个示例中,包含了 /etc/logrotate.d 中的所有文件。

这个示例还包含专门针对 /var/log/wtmp 和 /var/log/btmp 的规则,指定它们每月轮替一次。如果文件不存在,那么并不发出错误消息。创建一个新文件,并只保留一个备份。

在这个示例中,当备份到达最后一代时,就会删除它,因为没有指定其他的处理方法。

注意:/var/log/wtmp 和 /var/log/btmp 文件分别记录成功和不成功的登录尝试。与大多数日志文件不同,这些文件不是纯文本文件。可以使用 lastlastb 命令查看它们的内容。关于这些命令的细节,请参考手册页。

日志文件还可以在达到特定的大小时进行备份,还可以通过编写脚本在备份操作之前或之后运行命令。清单 24 给出一个更复杂的示例。

清单 24. 另一个 logrotate 配置示例
       /var/log/messages {
           rotate 5
           mail logsave@pinguino
           size 100k
            postrotate
               /usr/bin/killall -HUP syslogd
           endscript
       }

在这个示例中,/var/log/messages 在到达 100KB 之后轮替。保留五个备份,最旧的备份被发送到 logsave@pinguino。postrotate 引入一个脚本,这个脚本在完成轮替之后向 syslogd 守护进程发送一个 HUP 信号,从而重新启动 syslogd 守护进程。endscript 语句用于终止脚本,对于 prerotate 脚本也需要这个语句。更完整的信息参见 logrotate 手册页。

扫描日志文件以了解值得注意的活动

日志文件条目常常带时间戳,并包含报告消息的进程的主机名和进程名。清单 25 显示 /var/log/messages 中的几行,包含来自 gconfd、ntpd、init 和 yum 的条目。

清单 25. 日志文件条目示例
Jul  5 15:28:24 lyrebird gconfd (root-2832): Exiting
Jul  5 15:31:06 lyrebird ntpd[2063]: synchronized to 87.98.219.90, stratum 2
Jul  5 15:31:06 lyrebird ntpd[2063]: kernel time sync status change 0001
Jul  5 15:31:24 lyrebird init: Trying to re-exec init
Jul  5 15:31:24 lyrebird yum: Updated: libselinux.i386 2.0.14-2.fc7
Jul  5 15:31:24 lyrebird yum: Updated: libsemanage.i386 2.0.3-4.fc7
Jul  5 15:31:25 lyrebird yum: Updated: cups-libs.i386 1.2.11-2.fc7
Jul  5 15:31:25 lyrebird yum: Updated: libXfont.i386 1.2.9-2.fc7
Jul  5 15:31:27 lyrebird yum: Updated: NetworkManager.i386 0.6.5-7.fc7
Jul  5 15:31:27 lyrebird yum: Updated: NetworkManager-glib.i386 0.6.5-7.fc7

可以使用分页阅读程序(比如 less)扫描日志文件,还可以使用 grep 搜索特定的日志条目(比如来自主机 lyrebird 的内核消息),见清单 26。

清单 26. 扫描日志文件
[root@lyrebird ~]# less /var/log/messages
[root@lyrebird ~]# grep "lyrebird kernel" /var/log/messages | tail -n 9
Jul  5 15:26:46 lyrebird kernel: Bluetooth: HCI socket layer initialized
Jul  5 15:26:46 lyrebird kernel: Bluetooth: L2CAP ver 2.8
Jul  5 15:26:46 lyrebird kernel: Bluetooth: L2CAP socket layer initialized
Jul  5 15:26:46 lyrebird kernel: Bluetooth: RFCOMM socket layer initialized
Jul  5 15:26:46 lyrebird kernel: Bluetooth: RFCOMM TTY layer initialized
Jul  5 15:26:46 lyrebird kernel: Bluetooth: RFCOMM ver 1.8
Jul  5 15:26:46 lyrebird kernel: Bluetooth: HIDP (Human Interface Emulation) ver 1.2
Jul  5 15:26:59 lyrebird kernel: [drm] Initialized drm 1.1.0 20060810
Jul  5 15:26:59 lyrebird kernel: [drm] Initialized i915 1.6.0 20060119 on minor 0

监视日志文件

有时候需要监视日志文件。例如,可能希望捕捉一个不经常发生的事件。在这种情况下,可以使用 tail 命令和 -f 选项跟踪 日志文件。清单 27 给出一个示例。

清单 27. 跟踪日志文件更新
[root@lyrebird ~]# tail -n 1 -f /var/log/messages
Jul  6 15:16:26 lyrebird syslogd 1.4.2: restart.
Jul  6 15:16:26 lyrebird kernel: klogd 1.4.2, log source = /proc/kmsg started.
Jul  6 15:19:35 lyrebird yum: Updated: samba-common.i386 3.0.25b-2.fc7
Jul  6 15:19:35 lyrebird yum: Updated: procps.i386 3.2.7-14.fc7
Jul  6 15:19:36 lyrebird yum: Updated: samba-client.i386 3.0.25b-2.fc7
Jul  6 15:19:37 lyrebird yum: Updated: libsmbclient.i386 3.0.25b-2.fc7
Jul  6 15:19:46 lyrebird gconfd (ian-3267): Received signal 15, shutting down cleanly
Jul  6 15:19:46 lyrebird gconfd (ian-3267): Exiting
Jul  6 15:19:57 lyrebird yum: Updated: bluez-gnome.i386 0.8-1.fc7

跟踪日志文件中报告的问题

当在日志文件中发现问题时,需要注意产生这个问题的时间、主机名和进程。如果消息提供的信息足以判断问题的原因,那么就解决问题。如果信息不够充分,那么可能需要更新 syslog.conf,为适当的设施记录更多的消息。例如,可能需要显示警告消息之外的信息性消息,甚至是调试级消息。您的应用程序还可能有其他可以使用的设施。

最后,如果需要在日志文件中放上标志,帮助您了解在调试活动的哪个阶段记录了哪些消息,那么可以在终端窗口或 shell 脚本中使用 logger 命令,根据 syslog.conf 中的规则将选择的消息发送给 syslog 守护进程。

调度作业

本节介绍初级管理(LPIC-1)考试 102 的 1.111.4 主题的内容。这个主题的权值为 4。

在本节中,学习如何:

  • 使用 cronanacron 命令以一定的时间间隔运行作业
  • 使用 at 命令在指定的时间运行作业
  • 管理 cron 和 at 作业
  • 配置用户对 cron 和 at 服务的访问

在前一节中,学习了 logrotate 命令,并了解到需要定期运行它。在后面的两节中,会发现备份和网络时间服务也需要定期运行命令。许多管理任务都必须定期运行。在本节中,学习用来自动执行定期作业的工具,以及用来在特定时间运行作业的工具。

以一定的时间间隔运行作业

以一定的时间间隔运行作业需要使用 cron 设施进行管理,它由 crond 守护进程和一组表(描述执行哪些操作和采用什么样的频率)组成。这个守护进程每分钟唤醒一次,并通过检查 crontab 判断需要做什么。用户使用 crontab 命令管理 crontab。crond 守护进程常常是在系统启动时由 init 进程启动的。

为了简单,假设希望定期运行清单 28 所示的命令。这个命令实际上只报告日期和时间,其他什么事都不做,但是它可以说明如何使用 crontab 设置 cron 作业,而且还可以通过输出看到作业运行的时间。设置 crontab 条目需要一个包含转义的 shell 元字符的字符串,所以适合于简单的命令和参数。在这个示例中,将从脚本 /home/ian/mycrontab.sh 运行 echo 命令,这个脚本不需要参数。这可以减少处理转义字符的工作。

清单 28. 一个简单的命令示例
[ian@lyrebird ~]$ cat mycrontest.sh
#!/bin/bash
 echo "It is now $(date +%T) on $(date +%A)"
[ian@lyrebird ~]$ ./mycrontest.sh
It is now 18:37:42 on Friday

创建 crontab

使用 crontab 命令和 -e(表示 “edit”)选项创建 crontab。这会打开 vi 编辑器,除非在 EDITOR 或 VISUAL 环境变量中指定了另一种编辑器。

每个 crontab 条目包含六个字段:

  1. 分钟
  2. 小时
  3. 星期
  4. sh 执行的字符串

分钟和小时的范围分别是 0-59 和 0-12,日和月的范围分别是 1-31 和 1-12。星期的范围是 0-6,0 表示星期日。星期也可以指定为 sun、mon、tue 等等。第 6 个字段包含前 5 个字段之后的所有内容,它是要传递给 sh 的字符串。百分号(%)将转换为空行,所以如果要使用 % 或其他任何特殊字符,就要在前面加上反斜线(\)。第一个 % 之前的一行传递给 shell,这个 % 之后的所有行都作为标准输入传递。

各个与时间相关的字段可以指定一个单独的值、值的范围(比如 0-10 或 sun-wed)或者以逗号分隔的单独值和范围列表。清单 29 给出一个虚构的 crontab 条目示例。

清单 29. 一个简单的 crontab 示例
0,20,40 22-23 * 7 fri-sat /home/ian/mycrontest.sh

在这个示例中,我们的命令在 7 月的每个星期五和星期六晚上 10 点到午夜之间的第 0、20、40 分钟(每 20 分钟)执行。关于指定时间的其他方式的细节,参见 crontab(5) 的手册页。

输出

您可能想知道对来自命令的输出会如何处理。为使用 cron 而设计的大多数命令会使用前一节中学过的 syslog 在日志中记录输出。但是,定向到 stdout 的输出会通过电子邮件发送给用户。清单 30 给出我们的命令示例可能产生的输出。

清单 30. 通过电子邮件发送的 cron 输出
From ian@lyrebird.raleigh.ibm.com  Fri Jul  6 23:00:02 2007
Date: Fri, 6 Jul 2007 23:00:01 -0400
From: root@lyrebird.raleigh.ibm.com (Cron Daemon)
To: ian@lyrebird.raleigh.ibm.com
Subject: Cron <ian@lyrebird> /home/ian/mycrontest.sh
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/ian>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=ian>
X-Cron-Env: <USER=ian>

It is now 23:00:01 on Friday

crontab 存储在哪里?

crontab 命令创建的 crontab 存储在 /etc/spool/cron 下面的一个子目录中,这个子目录与创建 crontab 的用户同名,所以上面的 crontab 存储在 /etc/spool/cron/ian 中。因此,与前面学习的 passwd 命令一样,crontab 命令是一个用根权限运行的 suid 程序。

/etc/crontab

除了 /var/spool/cron 中的用户 crontab 文件之外,cron 还会检查 /etc/crontab 文件和 /etc/cron.d 目录中的文件。在这些系统 crontab 中,在第五个时间字段(星期)和命令之间增加了一个字段。这个字段指定应该为哪个用户运行这个命令,一般情况下是根用户。清单 31 给出一个 /etc/crontab 文件示例。

清单 31. /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

在这个示例中,真正的工作由 run-parts 命令执行,它运行 /etc/cron.hourly、/etc/cron.daily 等目录中的脚本;/etc/crontab 仅仅控制循环执行作业的时间。注意,这里的所有命令都作为根用户运行。还要注意,crontab 可以包含 shell 参数赋值,这些赋值会在运行命令之前执行。

anacron

cron 适合那些连续运行的系统。对于那些常常不开机的系统,比如笔记本计算机,可以使用另一个实用程序 anacron(表示 “anachronistic cron”)调度每日、每周或每月执行的作业。anacron 不处理每小时执行的作业。

anacron 在 /var/spool/anacron 中保留时间戳文件,记录作业运行的时间。当 anacron 运行时,它检查自作业上一次运行以来是否已经经过了所需的天数,如果需要,就运行作业。anacron 的作业表存储在 /etc/anacrontab 中,文件格式与 /etc/crontab 略有不同。与 /etc/crontab 一样,/etc/anacrontab 可以包含环境设置。每个作业有四个字段。

  1. 周期
  2. 延迟
  3. 作业标识符
  4. 命令

周期是天数,但是可以指定为 @monthly,这确保作业每个月只运行一次(无论这个月中有多少天)。延迟是在作业符合运行条件之后,到实际启动它之前等待的分钟数。可以使用这个设置防止在系统初次启动时集中执行作业。作业标识符可以包含除了斜线(/)之外的所有非空白字符。

/etc/crontab 和 /etc/anacrontab 都通过直接编辑进行更新。不使用 crontab 命令更新这些文件或 /etc/cron.d 目录中的文件。

在指定的时间运行作业

有时候,需要只运行作业一次而不是定期运行。为此,应该使用 at 命令。要运行的命令是从 -f 选项指定的文件读取的,如果没有使用 -f,那么从 stdin 读取。-m 选项向用户发送邮件,即使命令没有 stdout。-v 选项显示读取作业前运行作业的时间。这个时间也显示在输出中。清单 32 给出一个运行 mycrontest.sh 脚本的示例。清单 33 显示在运行作业之后通过邮件发送给用户的输出。注意,这里的输出比对应的 cron 作业输出要简单一些。

清单 32. 使用 at 命令
[ian@lyrebird ~]$ at -f mycrontest.sh -v 10:25
Sat Jul  7 10:25:00 2007

job 5 at Sat Jul  7 10:25:00 2007
清单 33. 来自 at 的作业输出
From ian@lyrebird.raleigh.ibm.com  Sat Jul  7 10:25:00 2007
Date: Sat, 7 Jul 2007 10:25:00 -0400
From: Ian Shields <ian@lyrebird.raleigh.ibm.com>
Subject: Output from your job        5
To: ian@lyrebird.raleigh.ibm.com

It is now 10:25:00 on Saturday

时间的设置可以非常复杂。清单 34 给出几个示例。参见 at 的手册页、/usr/share/doc/at/timespec 文件或 /usr/share/doc/at-3.1.10/timespec 这样的文件(这个示例中的 3.1.10 是 at 包的版本号)。

清单 34. at 命令使用的时间值
[ian@lyrebird ~]$ at -f mycrontest.sh  10pm tomorrow
job 14 at Sun Jul  8 22:00:00 2007
[ian@lyrebird ~]$ at -f mycrontest.sh 2:00 tuesday
job 15 at Tue Jul 10 02:00:00 2007
[ian@lyrebird ~]$ at -f mycrontest.sh 2:00 july 11
job 16 at Wed Jul 11 02:00:00 2007
[ian@lyrebird ~]$ at -f mycrontest.sh 2:00 next week
job 17 at Sat Jul 14 02:00:00 2007

at 命令还有一个 -q 选项。随着队列的增长,作业的 nice 值也会增长。还有一个 batch 命令,它与 at 命令相似,但是作业只在系统负载足够低时运行。这些特性的细节参见手册页。

管理调度的作业

列出调度的作业

可以管理 cron 和 at 作业。使用 crontab 命令和 -l 选项列出 crontab,使用 atq 命令显示用 at 命令加入队列中的作业,见清单 35。

清单 35. 显示调度的作业
[ian@lyrebird ~]$ crontab -l
0,20,40 22-23 * 7 fri-sat /home/ian/mycrontest.sh
[ian@lyrebird ~]$ atq
16      Wed Jul 11 02:00:00 2007 a ian
17      Sat Jul 14 02:00:00 2007 a ian
14      Sun Jul  8 22:00:00 2007 a ian
15      Tue Jul 10 02:00:00 2007 a ian

如果希望查看 at 调度执行的实际命令,那么可以使用 at 命令并加上 -c 选项和作业号。您会注意到,在发出 at 命令时生效的大多数环境设置会随调度的作业一起保存。清单 36 给出作业 15 的部分输出。

清单 36. 使用 at -c 并加上作业号
#!/bin/sh
# atrun uid=500 gid=500
# mail ian 0
umask 2
HOSTNAME=lyrebird.raleigh.ibm.com; export HOSTNAME
SHELL=/bin/bash; export SHELL
HISTSIZE=1000; export HISTSIZE
SSH_CLIENT=9.67.219.151\ 3210\ 22; export SSH_CLIENT
SSH_TTY=/dev/pts/5; export SSH_TTY
USER=ian; export USER
 ...
HOME=/home/ian; export HOME
LOGNAME=ian; export LOGNAME
 ...
cd /home/ian || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
${SHELL:-/bin/sh} << `(dd if=/dev/urandom count=200 bs=1 \
   2>/dev/null|LC_ALL=C tr -d -c '[:alnum:]')`

#!/bin/bash
 echo "It is now $(date +%T) on $(date +%A)"

注意,我们脚本文件的内容已经复制在一个 here-document 中,这个 here-document 将由 SHELL 变量指定的 shell 执行(如果没有设置 SHELL 变量,就使用 /bin/sh)。关于 here-document 的信息参见教程 “LPI 101 考试准备,主题 103:GNU 和 UNIX 命令”。

删除调度的作业

可以使用 cron 命令和 -r 选项删除所有调度的 cron 作业,见清单 37。

清单 37. 显示并删除 cron 作业
[ian@lyrebird ~]$ crontab -l
0,20,40 22-23 * 7 fri-sat /home/ian/mycrontest.sh
[ian@lyrebird ~]$ crontab -r
[ian@lyrebird ~]$ crontab -l
no crontab for ian

要删除系统 cron 或 anacron 作业,应该编辑 /etc/crontab、/etc/anacrontab 或者编辑或删除 /etc/cron.d 目录中的文件。

可以使用 atrm 命令加作业号删除用 at 命令调度的一个或多个作业。多个作业应该用空白分隔。清单 38 给出一个示例。

清单 38. 用 atq 和 atrm 显示并删除作业
[ian@lyrebird ~]$ atq
16      Wed Jul 11 02:00:00 2007 a ian
17      Sat Jul 14 02:00:00 2007 a ian
14      Sun Jul  8 22:00:00 2007 a ian
15      Tue Jul 10 02:00:00 2007 a ian
[ian@lyrebird ~]$ atrm 16 14 15
[ian@lyrebird ~]$ atq
17      Sat Jul 14 02:00:00 2007 a ian

配置用户对作业调度的访问

如果文件 /etc/cron.allow 存在,那么非根用户必须在其中列出,才能使用 crontab 和 cron 设施。如果 /etc/cron.allow 不存在,但是 /etc/cron.deny 存在,那么其中列出的非根用户不能使用 crontab 或 cron 设施。如果这两个文件都不存在,那么只允许超级用户使用这个命令。空的 /etc/cron.deny 文件允许所有用户使用 cron 设施,这是默认情况。

/etc/at.allow 和 /etc/at.deny 文件对 at 设施起相似的作用。

数据备份

本节介绍初级管理(LPIC-1)考试 102 的 1.111.5 主题的内容。这个主题的权值为 3。

在本节中,学习如何:

  • 制定备份策略
  • 将原始设备转储到文件,或从文件恢复原始设备
  • 执行部分备份和手工备份
  • 检验备份文件的完整性
  • 从备份部分地或完全恢复文件系统

制定备份策略

完善的备份是系统管理的必要部分,但是决定对什么进行备份以及何时和如何备份可能很复杂。数据库(比如客户订单或库存)常常对企业非常重要,许多数据库包含专用的备份和恢复工具,这些工具超出了本教程的范围。在另一个极端,一些文件是临时的,根本不需要备份。在本节中,我们主要关注系统文件和用户数据,并讨论数据备份的一些考虑事项、方法和工具。

有三种备份方式:

  1. 全(full) 备份是整个文件系统、目录或相关文件组的完整备份。创建全备份花费的时间最长,所以常常与另外两种方式之一结合使用。
  2. 差异(differential)累计(cumulative) 备份是上一次全备份以来修改过的所有内容的备份。在进行恢复时,需要最近的全备份和最新的差异备份。
  3. 增量(incremental) 备份只备份上一次增量备份以来的修改。在进行恢复时,需要最近的全备份以及上一次全备份以来的所有增量备份(按次序)。

对什么进行备份

在决定对什么进行备份时,应该考虑数据变化的频繁程度。这会帮助您决定数据备份的频率。与不太重要的数据相比,重要的数据应该更频繁地备份。操作系统可能很容易重新构建,尤其是在为几个系统使用同一映像的情况下,而对系统进行定制的文件应该是备份的重点。

对于编程人员来说,保留存储库(比如 CVS 存储库)的备份可能就足够了,各个程序员的沙箱可能不太重要。根据邮件对操作的重要性,可能设置不太频繁的备份就够了,也可能需要能够将邮箱恢复到尽可能近的日期。可能希望备份系统 cron 文件,但是不太关心各个用户的调度作业。

Filesystem Hierarchy Standard 提供了一个数据分类方法,这可以帮助您做出备份选择。细节参见教程 “LPI 101 考试准备:设备、Linux 文件系统和文件系统层次标准”。

决定了对什么进行备份之后,就需要决定进行全备份的频率,以及在这些全备份之间是否进行差异备份或增量备份。做了这些决定之后,下面的建议将帮助您选择合适的工具。

自动备份

在前一节中,您学习了如何调度作业,而 cron 设施很适合自动执行备份调度。但是,备份常常涉及可移除介质,尤其是磁带,所以可能需要操作员干预。应该创建并使用备份脚本,确保备份过程尽可能自动化且可重复。

转储和恢复原始设备

对文件系统进行全备份的一种方法是,制作它所在的分区的映像。可以作为一个顺序文件打开并读取原始设备(raw device),比如 /dev/hda1 或 /dev/sda2。同样,可以作为一个顺序文件从备份写原始设备。这不要求备份工具了解文件系统的布局,但是要求恢复到的空间至少与原来的空间一样大。一些处理原始设备的工具是文件系统感知的(filesystem aware),这意味着它们能够理解一个或多个 Linux 文件系统。这些实用程序可以转储原始设备,但是不转储分区中未使用的部分。它们可能要求恢复到相同或更大的分区,也可能不这么要求。dd 命令属于第一类备份工具,dump 命令属于第二类备份工具,它专门针对 ext2 和 ext3 文件系统。

dd 命令

在最简单的形式下,dd 命令将一个输入文件复制到一个输出文件,这两个文件都可以是原始设备。在备份原始设备时,比如 /dev/hda1 或 /dev/sda2,输入文件就是原始设备。在理想情况下,设备上的文件系统应该是未挂装的,至少应该是只读挂装的,从而确保在备份期间数据不会改变。清单 39 给出一个示例。

清单 39. 使用 dd 对分区进行备份
[root@lyrebird ~]# dd if=/dev/sda3 of=backup-1
2040255+0 records in
2040255+0 records out
1044610560 bytes (1.0 GB) copied, 49.3103 s, 21.2 MB/s

ifof 参数分别指定输入和输出文件。在这个示例中,输入文件是一个原始设备 dev/sda3,输出文件是根用户的主目录中的一个文件 backup-1。要将文件转储到磁带或软盘,应该指定 of=/dev/fd0of=/dev/st0 这样的设置。

注意,这里复制了 1,044,610,560 字节的数据,而且输出文件确实是这么大,但是这个分区中只有大约 3% 的空间实际使用了。除非要通过硬件压缩复制到磁带,否则很可能希望执行数据压缩。清单 40 给出一种数据压缩方法,并显示 lsdf 命令的输出,这些输出显示 /dev/sda3 上的文件大小和文件系统利用率。

清单 40. 使用 dd 执行备份和压缩
[root@lyrebird ~]# dd if=/dev/sda3 | gzip > backup-2
2040255+0 records in
2040255+0 records out
1044610560 bytes (1.0 GB) copied, 117.723 s, 8.9 MB/s
[root@lyrebird ~]# ls -l backup-[12]
-rw-r--r-- 1 root root 1044610560 2007-07-08 15:17 backup-1
-rw-r--r-- 1 root root  266932272 2007-07-08 15:56 backup-2
[root@lyrebird ~]# df -h /dev/sda3
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda3             972M   28M  944M   3% /grubfile

gzip 压缩将文件大小减小到未压缩文件的大约 20%。但是,未使用的块可能包含任意数据,所以压缩的备份仍然比分区上的数据总量大得多。

如果将大小除以 dd 处理的记录数,就会发现 dd 按照 512 字节的块大小写数据。在复制到磁带这样的原始设备时,这会导致操作效率很低,所以 dd 可以按照更大的块大小读写数据。指定 obs 选项来改变输出块大小,使用 ibs 选项指定输入块大小。还可以指定 bs,将输入和输出块大小设置为相同的值。

如果需要多个磁带或其他可移除存储介质来存储备份,那么需要用 split 这样的实用程序将备份分割为比较小的文件。

如果需要跳过磁盘或磁带标签等块,可以使用 dd 来设置。参见手册页中的示例。

除了复制数据之外,dd 命令还可以执行几种转换,比如 ASCII 和 EBCDIC 之间、big-endian 和 little-endian 之间或可变长度数据记录和固定长度数据记录之间的转换。显然,在复制真实文件(而不是原始设备)时,这些转换可能有用。细节参见手册页。

dump 命令

可以使用 dump 命令在 ext2 或 ext3 文件系统上执行全备份、差异备份或增量备份。清单 41 给出一个示例。

清单 41. 使用 dump 执行备份和压缩
[root@lyrebird ~]# dump -0 -f backup-4 -j -u /dev/sda3
  DUMP: Date of this level 0 dump: Sun Jul  8 16:47:47 2007
  DUMP: Dumping /dev/sda3 (/grubfile) to backup-4
  DUMP: Label: GRUB
  DUMP: Writing 10 Kilobyte records
  DUMP: Compressing output at compression level 2 (bzlib)
  DUMP: mapping (Pass I) [regular files]
  DUMP: mapping (Pass II) [directories]
  DUMP: estimated 12285 blocks.
  DUMP: Volume 1 started with block 1 at: Sun Jul  8 16:47:48 2007
  DUMP: dumping (Pass III) [directories]
  DUMP: dumping (Pass IV) [regular files]
  DUMP: Closing backup-4
  DUMP: Volume 1 completed at: Sun Jul  8 16:47:57 2007
  DUMP: Volume 1 took 0:00:09
  DUMP: Volume 1 transfer rate: 819 kB/s
  DUMP: Volume 1 12260kB uncompressed, 7377kB compressed, 1.662:1
  DUMP: 12260 blocks (11.97MB) on 1 volume(s)
  DUMP: finished in 9 seconds, throughput 1362 kBytes/sec
  DUMP: Date of this level 0 dump: Sun Jul  8 16:47:47 2007
  DUMP: Date this dump completed:  Sun Jul  8 16:47:57 2007
  DUMP: Average transfer rate: 819 kB/s
  DUMP: Wrote 12260kB uncompressed, 7377kB compressed, 1.662:1
  DUMP: DUMP IS DONE
[root@lyrebird ~]# ls -l backup-[2-4]
-rw-r--r-- 1 root root 266932272 2007-07-08 15:56 backup-2
-rw-r--r-- 1 root root 266932272 2007-07-08 15:44 backup-3
-rw-r--r-- 1 root root   7554939 2007-07-08 16:47 backup-4

在这个示例中,-0 指定转储级别(dump level),这是一个 0 到 9 之间的整数,0 表示全转储。-f 选项指定输出文件,这可以是原始设备。指定 - 将输出定向到 stdout。-j 选项指定压缩,默认的压缩级别是 2,使用 bzlib 压缩。如果愿意,也可以使用 -z 选项指定 zlib 压缩。-u 选项更新转储信息的记录(通常是 /etc/dumpdates)。选项后面的参数表示一个文件或文件列表,文件也可以是原始设备。注意,如果备份程序能够感知文件系统结构,备份就会小很多,因为可以避免保存设备上未使用的块。

如果输出到磁带这样的设备,当每个卷写满时,dump 命令会提示您提供另一个卷。也可以提供逗号分隔的多个文件名。例如,如果要进行一次无人值守的转储,它需要两个磁带,那么可以将磁带装在 /dev/st0 和 /dev/st1 上,调度转储命令并指定这两个磁带作为输出,然后您就可以回家睡觉了。

如果指定大于 0 的转储级别,那么会对最近一次低级别转储之后新增或修改过的所有文件执行增量转储。所以 1 级转储是差异转储,即使在这段时间内执行了 2 级或更高级别的转储。清单 42 更新 /dev/sda3 上一个现有文件的时间戳并创建一个新文件,然后执行 2 级转储。在此之后,创建另一个新文件并执行 1 级转储。还显示了来自 /etc/dumpdates 的信息。为了简单,省略了第二个转储输出的部分内容。

清单 42. 使用 dump 执行备份和压缩
[root@lyrebird ~]# dump -2 -f backup-5 -j -u /dev/sda3
  DUMP: Date of this level 2 dump: Sun Jul  8 16:55:46 2007
  DUMP: Date of last level 0 dump: Sun Jul  8 16:47:47 2007
  DUMP: Dumping /dev/sda3 (/grubfile) to backup-5
  DUMP: Label: GRUB
  DUMP: Writing 10 Kilobyte records
  DUMP: Compressing output at compression level 2 (bzlib)
  DUMP: mapping (Pass I) [regular files]
  DUMP: mapping (Pass II) [directories]
  DUMP: estimated 91 blocks.
  DUMP: Volume 1 started with block 1 at: Sun Jul  8 16:55:47 2007
  DUMP: dumping (Pass III) [directories]
  DUMP: dumping (Pass IV) [regular files]
  DUMP: Closing backup-5
  DUMP: Volume 1 completed at: Sun Jul  8 16:55:47 2007
  DUMP: 90 blocks (0.09MB) on 1 volume(s)
  DUMP: finished in less than a second
  DUMP: Date of this level 2 dump: Sun Jul  8 16:55:46 2007
  DUMP: Date this dump completed:  Sun Jul  8 16:55:47 2007
  DUMP: Average transfer rate: 0 kB/s
  DUMP: Wrote 90kB uncompressed, 15kB compressed, 6.000:1
  DUMP: DUMP IS DONE
[root@lyrebird ~]# echo "This data is even newer" >/grubfile/newerfile
[root@lyrebird ~]# dump -1 -f backup-6 -j -u -A backup-6-toc /dev/sda3
  DUMP: Date of this level 1 dump: Sun Jul  8 17:08:18 2007
  DUMP: Date of last level 0 dump: Sun Jul  8 16:47:47 2007
  DUMP: Dumping /dev/sda3 (/grubfile) to backup-6
   ...
  DUMP: Wrote 100kB uncompressed, 16kB compressed, 6.250:1
  DUMP: Archiving dump to backup-6-toc
  DUMP: DUMP IS DONE
[root@lyrebird ~]# ls -l backup-[4-6]
-rw-r--r-- 1 root root 7554939 2007-07-08 16:47 backup-4
-rw-r--r-- 1 root root   16198 2007-07-08 16:55 backup-5
-rw-r--r-- 1 root root   16560 2007-07-08 17:08 backup-6
[root@lyrebird ~]# cat /etc/dumpdates
/dev/sda3 0 Sun Jul  8 16:47:47 2007 -0400
/dev/sda3 2 Sun Jul  8 16:55:46 2007 -0400
/dev/sda3 1 Sun Jul  8 17:08:18 2007 -0400

注意,backup-6 确实比 backup-5 大。1 级转储使用 -A 选项创建一个内容目录,可以用它判断一个存档中是否包含某个文件,而不需要实际挂装这个存档。这对于磁带或其他可移除存档卷尤其有意义。在本节后面讨论数据恢复时,将看到一些示例。

dump 命令可以转储文件或子目录,但是不能更新 /etc/dumpdates,而且只支持 0 级全转储。

清单 43 使用 dump 命令将一个目录(/usr/include/bits)及其内容转储到软盘上。在这个示例中,一张软盘装不下整个转储,所以需要一个新卷。提示和响应用粗体显示。

清单 43. 使用 dump 将一个目录备份到多个卷
[root@lyrebird ~]# dump -0 -f /dev/fd0 /usr/include/bits
  DUMP: Date of this level 0 dump: Mon Jul  9 16:03:23 2007
  DUMP: Dumping /dev/sdb9 (/ (dir usr/include/bits)) to /dev/fd0
  DUMP: Label: /
  DUMP: Writing 10 Kilobyte records
  DUMP: mapping (Pass I) [regular files]
  DUMP: mapping (Pass II) [directories]
  DUMP: estimated 2790 blocks.
  DUMP: Volume 1 started with block 1 at: Mon Jul  9 16:03:30 2007
  DUMP: dumping (Pass III) [directories]
  DUMP: End of tape detected
  DUMP: Closing /dev/fd0
  DUMP: Volume 1 completed at: Mon Jul  9 16:04:49 2007
  DUMP: Volume 1 1470 blocks (1.44MB)
  DUMP: Volume 1 took 0:01:19
  DUMP: Volume 1 transfer rate: 18 kB/s
  DUMP: Change Volumes: Mount volume #2
  DUMP: Is the new volume mounted and ready to go?: ("yes" or "no") y
  DUMP: Volume 2 started with block 1441 at: Mon Jul  9 16:05:10 2007
  DUMP: Volume 2 begins with blocks from inode 2
  DUMP: dumping (Pass IV) [regular files]
  DUMP: Closing /dev/fd0
  DUMP: Volume 2 completed at: Mon Jul  9 16:06:28 2007
  DUMP: Volume 2 1410 blocks (1.38MB)
  DUMP: Volume 2 took 0:01:18
  DUMP: Volume 2 transfer rate: 18 kB/s
  DUMP: 2850 blocks (2.78MB) on 2 volume(s)
  DUMP: finished in 109 seconds, throughput 26 kBytes/sec
  DUMP: Date of this level 0 dump: Mon Jul  9 16:03:23 2007
  DUMP: Date this dump completed:  Mon Jul  9 16:06:28 2007
  DUMP: Average transfer rate: 18 kB/s
  DUMP: DUMP IS DONE

如果备份到磁带,那么要记住磁带常常在每个操作之后回卷(rewind)。使用 /dev/st0 或 /dev/st1 这样的名称的设备会自动回卷。对应的非回卷设备是 /dev/nst0 和 /dev/nst1。在任何时候,都可以使用 mt 命令执行磁带操作,比如前进、后退、回卷和写 EOF 标志。关于 mtst 的更多信息参见手册页。

如果恰当地选择了转储级别,就可以尽可能减少恢复到任何级别所需的存档数量。在 dump 手册页中提供了一种基于 Towers of Hanoi 迷题的建议。

dd 命令一样,还有许多选项没有在这里讨论。更多细节参见手册页。

部分备份和手工备份

到目前为止,已经学习了用来备份整个文件系统的工具。有时候,需要备份选择的文件或子目录,而不是备份整个文件系统。例如,可能需要每周备份系统的大多数部分,但是每天备份邮件文件。通常使用另两个程序 cpiotar 执行这样的操作。这两个程序可以将存档写到文件或设备(比如磁带或软盘),它们还可以从这些存档执行恢复。在这两个程序之中,tar 更常用,这可能是因为它能够更好地处理完整的目录,而且 GNU tar 支持 gzip 和 bzip 压缩。

使用 cpio

cpio 命令采用 copy-out 模式创建存档,用 copy-in 模式恢复存档,用 copy-pass 模式将一组文件从一个位置复制到另一个位置。对于 copy-out 模式使用 -o--create 选项,对于 copy-in 模式使用 -i--extract 选项,对于 copy-pass 模式使用 -p--pass-through 选项。输入是通过 stdin 提供的一系列文件。输出发送到 stdout,或者发送到 -f--file 选项指定的设备或文件。

清单 44 演示如何使用 find 命令生成一个文件列表。注意,在 find 中使用 -print0 选项生成 null 结尾的文件名字符串,在 cpio 上使用 --null 选项读取这种格式。这样就可以正确地处理包含空格或换行符的文件名。

清单 44. 使用 cpio 备份目录
[root@lyrebird ~]#  find ~ian -depth -print0 | cpio --null -o >backup-cpio-1
18855 blocks

如果希望在文件存档时列出文件,可以在 cpio 中添加 -v 选项。

与可以存档到磁带的其他命令一样,可以指定块大小。其他选项的细节参见手册页。

使用 tar

tar(这个名称源自 Tape ARchive)从一组输入文件或目录创建一个存档文件,也称为 tarfiletarball;它还可以从这样的存档恢复文件。如果提供一个目录作为 tar 的输入,那么会自动包含其中的所有文件和子目录,所以使用 tar 存档目录结构的子树是非常方便的。

与前面讨论的其他存档命令一样,输出可以发送到文件、磁带或磁盘等设备或 stdout。输出位置用 -f 选项指定。常用的其他选项包括:-c 用于创建存档,-x 用于提取存档,-v 提供详细输出,它会列出正在处理的文件,-z 执行 gzip 压缩,-j 执行 bzip2 压缩。大多数 tar 选项有短格式(使用一个连字符)和长格式(使用两个连字符)。这里解释短格式。关于长格式和其他选项的信息参见手册页。

清单 45 演示如何使用 tar 创建系统 cron 作业的备份。

清单 45. 使用 tar 备份系统 cron 作业
[root@lyrebird ~]# tar -czvf backup-tar-1 /etc/*crontab /etc/cron.d
tar: Removing leading `/' from member names
/etc/anacrontab
/etc/crontab
/etc/cron.d/
/etc/cron.d/sa-update
/etc/cron.d/smolt

在输出的第一行上指出,tar 将删除成员名中的前导斜线(/)。这允许在替换系统文件之前将文件恢复到其他位置进行检查。在创建存档时,最好避免混合使用绝对路径名和相对路径名,因为从存档恢复文件时所有路径都是相对的。

tar 命令可以使用 -r--append 选项在存档中追加文件。这可能导致一个存档中出现一个文件的多个副本。在这种情况下,在恢复操作期间将恢复最近的 副本。可以使用 --occurrence 选项在多个副本中选择特定的文件。如果存档在常规文件系统而不是磁带上,那么可以使用 -u--update 选项更新存档。这与在存档中追加文件相似,不同之处在于,会对存档中文件的时间戳和文件系统中的时间戳进行比较,并只追加那些在存档版本之后修改过的文件。正如前面提到的,这不适用于磁带存档。

与前面讨论的其他命令一样,还有许多选项没有在这里讨论。更多细节参见手册页。

备份文件的完整性

备份文件的完整性极其重要。如果备份文件是坏的,备份就没有意义了。良好的备份策略应该检查备份。

确保备份完整性的第一步是,确保正确地捕捉了要备份的数据。如果文件系统未挂装或采用只读挂装,这往往很容易,因为在备份期间要备份的数据不会发生变化。如果在进行备份时要备份的文件系统、目录或文件可能发生修改,那么应该确认在备份期间没有发生修改。如果发生了修改,就需要捕捉这些修改的策略,可以重复执行备份,也可以替换备份中受影响的文件。无论如何,这也会影响恢复过程。

为了确保备份是良好的,需要定期检查备份。一种方法是,将备份恢复到空闲的卷并检查其内容。最好先进行这样的检查,然后再在备份的文件系统上允许更新。如果备份到 CD 或 DVD 这样的介质,那么可以在备份过程中使用 diff 命令来确保备份是良好的。请记住,良好的备份在存储中也可能损坏,所以即使在备份时做了检查,也应该定期进行检查。使用 md5sumsha1sum 等程序生成摘要也有助于检查备份文件的完整性。

从备份恢复文件系统

与文件备份功能相对的功能就是在需要时恢复它们。有时候希望恢复整个文件系统,但更常见的情况是只需要恢复特定的文件或目录。在一般情况下,会先将文件恢复到某个临时空间,确认恢复的内容确实是您需要的,而且与系统的当前状态一致,然后再将恢复的文件放到正确的位置。

一个相关问题是,需要确认您需要的文件版本确实包含在某个备份文件中,因为用户常常需要访问 “在过去一两周内” 修改过或删除的一个文件版本。考虑到这些问题,我们来介绍一些恢复选项。

恢复 dd 存档

dd 命令不是文件系统感知的,所以需要先恢复一个分区的转储,然后才能了解其中的内容。清单 46 将前面清单 39 转储的分区恢复到分区 /dev/sdc7,这个分区是在一个可移除的 USB 驱动器上专门为此创建的。

清单 46. 使用 dd 恢复分区
[root@lyrebird ~]# dd if=backup-1 of=/dev/sdc7
2040255+0 records in
2040255+0 records out
1044610560 bytes (1.0 GB) copied, 44.0084 s, 23.7 MB/s

在建立这个备份之后,我们在 /dev/sda3 上的文件系统中添加了一些文件。如果挂装刚恢复的分区并与原来的分区进行比较,就会发现它们确实有差异,见清单 47。注意,用 touch 更新了时间戳的文件没有在这里出现。

清单 47. 对比恢复的分区和当前状态
[root@lyrebird ~]# mount /dev/sdc7 /mnt/temp-dd/
[root@lyrebird ~]# diff -rq /grubfile/ /mnt/temp-dd/
Only in /grubfile/: newerfile
Only in /grubfile/: newfile

使用 restore 恢复 dump 存档

我们在前面使用 dump 做了一次差异备份,还创建了一个内容目录。清单 48 使用 restore 检查 dump 创建的存档中的文件,并且是通过使用存档本身(backup-5)和内容目录(backup-6-toc)两种方式。

清单 48. 检查存档的内容
[root@lyrebird ~]# restore -t -f backup-5
Dump tape is compressed.
Dump   date: Sun Jul  8 16:55:46 2007
Dumped from: Sun Jul  8 16:47:47 2007
Level 2 dump of /grubfile on lyrebird.raleigh.ibm.com:/dev/sda3
Label: GRUB
         2      .
    100481      ./ibshome
    100482      ./ibshome/index.html
        16      ./newfile
[root@lyrebird ~]# restore -t -A backup-6-toc
Dump   date: Sun Jul  8 17:08:18 2007
Dumped from: Sun Jul  8 16:47:47 2007
Level 1 dump of /grubfile on lyrebird.raleigh.ibm.com:/dev/sda3
Label: GRUB
Starting inode numbers by volume:
        Volume 1: 2
         2      .
    100481      ./ibshome
    100482      ./ibshome/index.html
        16      ./newfile
        17      ./newerfile

restore 命令还可以使用 -C 选项比较存档的内容和文件系统的内容。在清单 49 中,我们更新了 newerfile,然后比较备份和文件系统。

清单 49. 使用 restore 比较存档和文件系统
[root@lyrebird ~]# echo "something different" >/grubfile/newerfile
[root@lyrebird ~]# restore -C -f backup-6
Dump tape is compressed.
Dump   date: Sun Jul  8 17:08:18 2007
Dumped from: Sun Jul  8 16:47:47 2007
Level 1 dump of /grubfile on lyrebird.raleigh.ibm.com:/dev/sda3
Label: GRUB
filesys = /grubfile
./newerfile: size has changed.
Some files were modified!  1 compare errors

restore 命令可以执行交互式恢复或自动恢复。清单 50 将 newerfile 恢复到根用户的主目录(这样就可以在用它替换更新的文件之前检查它),然后用备份副本替换更新的文件。这个示例演示交互式恢复。

清单 50. 使用 restore 恢复一个文件
[root@lyrebird ~]# restore -i -f backup-6
Dump tape is compressed.
restore > ?
Available commands are:
        ls [arg] - list directory
        cd arg - change directory
        pwd - print current directory
        add [arg] - add `arg' to list of files to be extracted
        delete [arg] - delete `arg' from list of files to be extracted
        extract - extract requested files
        setmodes - set modes of requested directories
        quit - immediately exit program
        what - list dump header information
        verbose - toggle verbose flag (useful with ``ls'')
        prompt - toggle the prompt display
        help or `?' - print this list
If no `arg' is supplied, the current directory is used
restore > ls new*
newerfile
newfile
restore > add newerfile
restore > extract
You have not read any volumes yet.
Unless you know which volume your file(s) are on you should start
with the last volume and work towards the first.
Specify next volume # (none if no more volumes): 1
set owner/mode for '.'? [yn] y
restore > q
[root@lyrebird ~]# mv -f newerfile /grubfile

恢复 cpio 存档

采用 copy-in 模式的 cpio 命令(-i--extract 选项)可以列出存档的内容或者恢复选择的文件。在列出文件时,指定 --absolute-filenames 选项就会去掉每个路径开头的前导 / 字符,可以减少 cpio 产生的无关消息量。清单 51 给出一个存档的部分输出。

清单 51. 使用 cpio 列出存档内容
[root@lyrebird ~]# cpio  -id --list --absolute-filenames <backup-cpio-1
/home/ian/.gstreamer-0.10/registry.i686.xml
/home/ian/.gstreamer-0.10
/home/ian/.Trash/gnome-terminal.desktop
/home/ian/.Trash
/home/ian/.bash_profile

清单 52 演示如何恢复所有在路径名或文件名中包含 “samp” 的文件。输出经过 uniq 的处理,减少了 “Removing leading '/' ...” 消息的数量。必须指定 -d 选项来创建目录;否则,会在当前目录中创建所有文件。另外,除非指定了 -u--unconditional 选项,否则 cpio 不会用存档副本替换文件系统中任何更新的文件。

清单 52. 使用 cpio 恢复选择的文件
[root@lyrebird ~]# cpio  -ivd "*samp*" < backup-cpio-1 2>&1 |uniq
cpio: Removing leading `/' from member names
home/ian/crontab.samp
cpio: Removing leading `/' from member names
home/ian/sample.file
cpio: Removing leading `/' from member names
18855 blocks

恢复 tar 存档

tar 也可以比较存档和当前的文件系统,以及从存档恢复文件。使用 -d--compare--diff 选项执行比较。输出会显示内容不同的文件和时间戳不同的文件。清单 53 用 touch 命令改变 /etc 中一个文件的时间戳,然后比较存档和文件系统,并提供详细输出(使用 -v 选项)。directory / 选项让 tar 从根目录开始执行比较,而不是从当前目录。

清单 53. 使用 tar 比较存档和文件
[root@lyrebird ~]# touch /etc/crontab
[root@lyrebird ~]# tar --diff -vf backup-tar-1 --directory /
etc/anacrontab
etc/crontab
etc/crontab: Mod time differs
etc/cron.d/
etc/cron.d/sa-update
etc/cron.d/smolt

清单 54 演示如何只将 /etc/crontab 和 /etc/anacrontab 两个文件提取到当前目录中。

清单 54. 使用 tar 提取存档文件
[root@lyrebird ~]# tar -xzvf backup-tar-1 "*tab"
etc/anacrontab
etc/crontab

注意,tarcpio 正好相反,它会自动创建目录层次结构。

本教程的下一节讲解如何维护系统时间。

系统时间

本节介绍初级管理(LPIC-1)考试 102 的 1.111.6 主题的内容。这个主题的权值为 4。

在本节中,学习如何:

  • 设置系统日期和时间
  • 将 BIOS 时钟设置为正确的 UTC 时间
  • 配置时区
  • 配置 Network Time Protocol(NTP)服务,包括纠正时钟漂移

设置系统日期和时间

Linux 上的系统时间非常重要。在前面已经看到,cron 和 anacron 设施根据时间执行作业,所以它们需要精确的时间。前一节中讨论的大多数备份和恢复工具,以及 make 等开发工具,也依赖于可靠的时间。1980 年以后生产的大多数计算机都包含某种时钟机制,1984 年以后生产的大多数计算机通常有持久的时钟机制,即使计算机关闭了,仍然可以维护时间。

如果以图形化方式安装 Linux 系统,那么可能根据自己的需要设置了时钟和时区。还可以使用 Network Time Protocol(NTP)设置时钟,可以使用 Coordinated Universal Time(UTC)维护系统时钟。如果用 Fedora、Red Hat 或相似系统上的图形工具设置过时钟,您可能见过图 3 这样的对话框。

图 3. 更新日期和时间
更新日期和时间
更新日期和时间

令人吃惊的是,实际上无法用这个对话框设置时钟。在本节中,学习本地时钟和 NTP 之间的差异以及如何设置系统时间。

无论您生活在 New York、Budapest、Nakhodka、Ulan Bator、Bangkok 还是 Canberra,大多数 Linux 时间的计算都与 Coordinated Universal Time(UTC)相关。如果使用专有的 Linux 系统,往往会将硬件时钟设置为 UTC;但是,如果还要引导另一个操作系统(比如 Windows),那么可能需要将硬件时钟设置为本地时间。这一般不是问题,因为 Linux 会负责处理,但是 Linux 内部有两种跟踪时区的方法;如果它们不一致,在 FAT 文件系统上可能会产生一些奇怪的时间戳和其他现象。清单 55 演示如何使用 date 命令显示当前日期和时间。显示的总是本地时间,即使硬件时钟设置为 UTC 时间。

清单 55. 显示当前日期和时间
[root@lyrebird ~]# date;date -u
Mon Jul  9 22:40:01 EDT 2007

date 命令支持许多输出格式,在 清单 28 中已经看到过其中一些格式。如果想进一步了解各种日期格式,请参考 date 的手册页。

如果需要设置日期,那么可以提供日期和时间参数。出于历史原因,所需的格式对于美国人来说有点儿古怪,对于其他地区的人甚至更奇怪。必须至少按照 MMDDhhmm 格式指定月、日、小时和分钟,还可以加上两位或四位的年份(CCYY 或 YY)以及可选的点号(.),后面加上两位的秒数。清单 56 设置了系统日期。

清单 56. 设置系统日期和时间
[root@lyrebird ~]# date; date 0709221407;date
Mon Jul  9 23:12:37 EDT 2007
Mon Jul  9 22:14:00 EDT 2007
Mon Jul  9 22:14:00 EDT 2007

将 BIOS 时钟设置为 UTC 时间

Linux 系统和大多数其他现代操作系统实际上有两个时钟。第一个时钟是硬件时钟,有时称为 Real Time Clock(RTC)或 BIOS 时钟,这个时钟常常与石英晶体的振荡频率相关,它的误差只有每天几秒。它会受到环境温度等因素的影响。第二个时钟是内部软件时钟,这由计数系统中断控制。它会受到系统高负载和中断延迟的影响。系统通常会在启动时读取硬件时钟,在此之后使用软件时钟。date 命令设置软件时钟,而不是硬件时钟。

如果使用 Network Time Protocol(NTP),那么可以在安装系统时设置硬件时钟,然后就不用再管它了。如果不使用 NTP,本节将讲解如何显示和设置硬件时钟时间。

可以使用 hwclock 命令显示硬件时钟的当前值。清单 57 同时显示系统时钟和硬件时钟的当前值。

清单 57. 系统时钟和硬件时钟值
[root@lyrebird ~]# date;hwclock
Mon Jul  9 22:16:11 EDT 2007
Mon 09 Jul 2007 11:14:49 PM EDT  -0.071616 seconds

注意,这两个值有差异。可以使用 hwclock-w--systohc 选项让硬件时钟与系统时钟同步。可以使用 -s--hctosys 选项让系统时钟与硬件时钟同步,见清单 58。

清单 58. 按照硬件时钟设置系统时钟
[root@lyrebird ~]# date;hwclock;hwclock -s;date
Mon Jul  9 22:20:23 EDT 2007
Mon 09 Jul 2007 11:19:01 PM EDT  -0.414881 seconds
Mon Jul  9 23:19:02 EDT 2007

可以指定 --utc--localtime 选项,让系统时钟与 UTC 或本地时间同步。如果没有指定值,就从 /etc/adjtime 的第三行获得值。

Linux 内核有一种模式,它每 11 分钟将系统时间复制到硬件时钟。默认情况下这个模式是关闭的,但是 NTP 会打开它。如果以老式方式设置时间,比如 hwclock --hctosys,就会关闭这个模式,所以如果使用 NTP,最好让 NTP 自己负责,不要手工设置时间。在 adjtimex 的手册页中介绍了如何检查时钟是否每 11 分钟更新。可能需要安装 adjtimex 包,因为默认情况下可能没有安装这个包。

hwclock 命令会记录对硬件时钟的修改,以便补偿时钟频率的误差。必需的数据点保存在 /etc/adjtime 中,这是一个 ASCII 文件。如果不使用 Network Time Protocol,那么可以使用 adjtimex 命令补偿时钟漂移。如果使用 NTP,NTP 大约每 11 分钟调整一次硬件时钟。除了显示硬件时钟是本地时间还是 UTC 时间之外,/etc/adjtime 中的第一个值还显示每天的硬件时钟漂移量(以秒为单位)。清单 59 给出两个示例。

清单 59. /etc/adjtime 显示时钟漂移和本地时间或 UTC 时间
[root@lyrebird ~]# cat /etc/adjtime
0.000990 1184019960 0.000000
1184019960
LOCAL
root@pinguino:~# cat /etc/adjtime
-0.003247 1182889954 0.000000
1182889954
LOCAL

注意,这两个系统都按照本地时间记录硬件时钟,但是时钟漂移不一样 — 在 lyrebird 上是 0.000990,在 pinguino 上是 -0.003247。

配置时区

时区表示本地时间与 UTC 相差多少。可以配置关于时区的信息,这些信息保存在 /usr/share/zoneinfo 中。/tec/localtime 以前常常是指向这个目录树中一个时区文件的链接,例如 /usr/share/zoneinfo/Eire 或 /usr/share/zoneinfo/Australia/Hobart。在现代系统上,它往往是适当时区数据文件的副本,因为在引导过程的早期需要本地时区信息,但是这时候 /usr/share 文件系统可能还没有挂装。

同样,另一个文件 /etc/timezone 以前常常是 /etc/default/init 的链接,它用来设置时区环境变量 TZ 和几个与地区相关的环境变量。您的系统上可能有这个文件,也可能没有。如果有这个文件,它可能只包含当前时区的名称。还可能在 /etc/sysconfig/clock 中找到时区信息。清单 60 显示 Ubuntu 7.04 和 Fedora 7 系统上的这些文件。

清单 60. /etc 中的时区信息
root@pinguino:~# cat /etc/timezone
America/New_York

[root@lyrebird ~]# cat /etc/sysconfig/clock
# The ZONE parameter is only evaluated by system-config-date.
# The timezone of the system is defined by the contents of /etc/localtime.
ZONE="America/New York"
UTC=false
ARC=false

Debian 和 Ubuntu 等系统用 tzconfig 命令设置时区。Fedora 等其他系统使用 system-config-date 设置时区并指出时钟是否使用 UTC。清单 61 使用 tzconfig 命令显示当前时区。

清单 61. 用 tzconfig 设置时区
root@pinguino:~# tzconfig
Your current time zone is set to America/New_York
Do you want to change that? [n]:
Your time zone will not be changed

配置 Network Time Protocol

Network Time ProtocolNTP)是一种通过网络对计算机时钟进行同步的协议。通常是与 UTC 同步。

NTP 3 是一个互联网标准草案(RFC 1305)。当前正在开发的版本(NTP 4)是一个重要的修订版,当前还没有完成。RFC 4330 描述了 Simple NTP(SNTP)4。

时间同步是通过向时间服务器(time server) 发送消息来完成的。对于返回的时间,要用网络往返延迟时间的一半进行调整。因此,时间的精度依赖于网络延迟,以及两个方向上的延迟是否大致相同。到时间服务器的路径越短,时间的精度就可能越高。更详细的信息参见 参考资料

互联网上的计算机非常多,所以时间服务器组织成一个层(stratum)。很少的几台 1 级服务器通过原子钟这样的时间源维护非常精确的时间。数量较多的 2 级服务器从 1 级服务器获得时间,并向数量更多的 3 级服务器提供时间,以此类推。为了减轻时间服务器的负载,有许多志愿者通过 pool.ntp.org 提供时间服务(参见 参考资料 中的链接)。循环式 DNS 服务器将 NTP 服务器请求分布在可用服务器池中,从而实现 NTP 负载平衡。

如果使用图形界面,那么可以使用与图 4 相似的对话框设置 NTP 时间服务器。这个系统使用 NTP 自动更新时间,所以图 3 中的对话框不允许修改日期和时间。

图 4. 设置 NTP 服务器
设置 NTP 服务器
设置 NTP 服务器

NTP 配置信息保存在 /etc/ntp.conf 中,所以也可以编辑这个文件,然后保存文件并重新启动 ntpd 守护进程。清单 62 给出一个 /etc/ntp.conf 文件示例,它使用图 4 中的时间服务器。

清单 62. /etc/ntp.conf 文件示例
[root@lyrebird ~]# cat /etc/ntp.conf
# Permit time synchronization with our time source, but do not
# permit the source to query or modify the service on this system.
restrict default kod nomodify notrap nopeer noquery

# Permit all access over the loopback interface.  This could
# be tightened as well, but to do so would effect some of
# the administrative functions.
restrict 127.0.0.1

# Hosts on local network are less restricted.
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).

#broadcast 192.168.1.255 key 42         # broadcast server
#broadcastclient        # broadcast client
#broadcast 224.0.1.1 key 42             # multicast server
#multicastclient 224.0.1.1              # multicast client
#manycastserver 239.255.254.254         # manycast server
#manycastclient 239.255.254.254 key 42  # manycast client

# Undisciplined Local Clock. This is a fake driver intended for backup
# and when no outside source of synchronized time is available.
#server 127.127.1.0  # local clock
#fudge 127.127.1.0 stratum 10

# Drift file.  Put this in a directory which the daemon can write to.
# No symbolic links allowed, either, since the daemon updates the file
# by creating a temporary in the same directory and then rename()'ing
# it to the file.
driftfile /var/lib/ntp/drift

# Key file containing the keys and key identifiers used when operating
# with symmetric key cryptography.
keys /etc/ntp/keys

# Specify the key identifiers which are trusted.
#trustedkey 4 8 42

# Specify the key identifier to use with the ntpdc utility.
#requestkey 8

# Specify the key identifier to use with the ntpq utility.
#controlkey 8
server 0.us.pool.ntp.org
restrict 0.us.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery
server 1.us.pool.ntp.org
restrict 1.us.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery
server 2.us.pool.ntp.org
restrict 2.us.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery

如果要使用 pool.ntp.org 时间服务器,世界各地都有这些服务器。通过限制使用的服务器,常常可以获得更准确的时间;例如在这个示例中,使用 us.pool.ntp.org,因此只选择美国的服务器。关于 ntp.pool.org 项目的更多信息参阅 参考资料

NTP 命令

可以使用 ntpdate 命令按照 NTP 时间服务器设置系统时间,见清单 63。

清单 63. 使用 ntpdate 命令按照 NTP 服务器设置系统时间
[root@lyrebird ~]# ntpdate 0.us.pool.ntp.org
10 Jul 10:27:39 ntpdate[15308]: adjust time server 66.199.242.154 offset -0.007271 sec

因为服务器采用循环模式,所以下一次运行这个命令时可能会看到另一个服务器。清单 64 显示在运行上面的 ntpdate 命令之后,对 0.us.ntp.pool.org 的前几个 DNS 响应。

清单 64. 循环式 NTP 服务器池
[root@lyrebird ~]# dig 0.pool.ntp.org +noall +answer | head -n 5
0.pool.ntp.org.  1062   IN      A       217.116.227.3
0.pool.ntp.org.  1062   IN      A       24.215.0.24
0.pool.ntp.org.  1062   IN      A       62.66.254.154
0.pool.ntp.org.  1062   IN      A       76.168.30.201
0.pool.ntp.org.  1062   IN      A       81.169.139.140

ntpdate 命令现在已经废弃了,因为使用 ntpq 命令和 -q 选项可以实现同样的功能,见清单 65。

清单 65. 使用 ntpd -q 设置系统时间
[root@lyrebird ~]# ntpd -q
ntpd: time slew -0.014406s

注意,ntpd 命令使用来自 /etc/ntp.conf 或命令行上提供的配置文件的时间服务器信息。关于 ntpd 的更多信息参见手册页。还要注意,如果 ntpd 守护进程正在运行,那么 ntpd -q 会悄悄退出,并在 /var/log/messages 中记录一个失败消息。

另一个相关命令是 ntpq 命令,可以用它查询 NTP 守护进程。更多细节参见手册页。

本教程现在结束了。我们讨论了关于系统管理的许多主题。不要忘记 对本教程的评价 并向我们提供反馈。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Linux, Open source
ArticleID=246410
ArticleTitle=LPI 102 考试准备,主题 111: 管理任务
publish-date=08092007