注意:
- Oracle 提供的免费实验室环境中提供了此教程。
- 它使用 Oracle Cloud Infrastructure 身份证明、租户和区间的示例值。完成实验室时,请将这些值替换为特定于云环境的值。
在 Oracle Linux 上管理系统时间和调度任务
简介
Oracle Linux 为用户提供了多种方式与时间和日期进行交互。虽然可以手动更改这些属性,但配置实现网络时间协议 (Network Time Protocol,NTP) 的服务(例如 chrony )更为常见。这样,系统时间将保持正确,使用 cron
或 systemd timers
的任何任务都会按计划运行。
目标
在本教程中,您将学习:
- 使用
date
、hwclock
和timedatectl
从终端管理系统时间 - 运行并启用同步服务
- 使用 cron 和 systemd timers 调度任务
先决条件
-
最少一个 Oracle Linux 系统
-
每个系统都应安装 Oracle Linux 并进行以下配置:
- 具有 sudo 访问权限的非 root 用户帐户
- 访问 Internet
部署 Oracle Linux
注:如果在您自己的租户中运行,请在部署实验环境之前阅读 linux-virt-labs
GitHub 项目 README.md 并完成先决条件。
-
在 Luna Desktop 上打开一个终端。
-
克隆
linux-virt-labs
GitHub 项目。git clone https://github.com/oracle-devrel/linux-virt-labs.git
-
转到工作目录。
cd linux-virt-labs/ol
-
安装所需集合。
ansible-galaxy collection install -r requirements.yml
-
部署实验室环境。
ansible-playbook create_instance.yml -e localhost_python_interpreter="/usr/bin/python3.6"
免费的实验环境需要额外的变量
local_python_interpreter
,该变量为在 localhost 上运行的播放设置ansible_python_interpreter
。此变量是必需的,因为环境安装了适用于 Python 的 Oracle Cloud Infrastructure SDK 的 RPM 程序包,该程序包位于 python3.6 模块下。默认部署配置使用 AMD CPU 和 Oracle Linux 8。要使用 Intel CPU 或 Oracle Linux 9,请将
-e instance_shape="VM.Standard3.Flex"
或-e os_version="9"
添加到部署命令。重要提示:等待手册成功运行并到达暂停任务。在手册的这一阶段,Oracle Linux 安装已完成,实例已准备就绪。记下之前的剧集,其中输出其部署的节点的公共和专用 IP 地址,以及运行实验时所需的任何其他部署信息。
配置系统日期和时间
Oracle Linux 有三个常用的命令,可帮助您调整系统上的日期和时间。date
命令调整系统时间,而 hwclock
调整 RTC 时间。在 Oracle Linux 中,RTC 时间是指实时时钟 (Real-Time Clock,RTC) 保持的时间,实时时钟 (Real-Time Clock,RTC) 是电池支持的硬件时钟,在关闭系统电源时会继续运行。硬件时钟的其他常见名称包括 CMOS 时钟或 BIOS 时钟。如果要更新 date
更改后的 RTC 时钟,必须运行 hwclock
。
第三个选项是 timedatectl
。此命令将 date
和 hwclock
组合在一起,并在设置时间时更新系统和 RTC。在基于 systemd 的现代 Linux 发行版(例如 Oracle Linux)上,建议使用 timedatectl
。
显示和设置系统时钟
-
打开终端并通过 SSH 连接到 ol-node-01 实例。
ssh oracle@<ip_address_of_instance>
-
获取当前系统时间和日期。
date
输出以默认格式显示系统的日期、时间和时区。可以使用
date
命令的许多参数更改输出的格式。这些参数有助于编写脚本或计算不同的日期和时间。通过运行date --help
查找更多信息,或使用man date
查看手册页。 -
调整系统时间和日期。
sudo date -s "1 JAN 1970 16:00:00"
-
使用格式控制参数简化格式。
sudo date +%Y%m%d -s "20250203"
请注意,由于您未提供时间,因此时间部分默认为所有零,即午夜。
-
设置系统时间。
sudo date +%T -s "14:08:14"
如果再次运行
date
命令,则应根据输入的内容显示时间。
显示和设置硬件时钟
-
读取当前硬件时钟 (hardware clock,RTC)。
sudo hwclock --show
-
根据硬件时钟设置系统时钟。
sudo hwclock -s
该命令允许您通过传递
-w
函数来设置相反方向的时钟。通过运行hwclock --help
或查看手册页man hwclock
来查看其他函数和选项。
使用 Systemd 的日期和时间
-
获取当前日期和时间。
timedatectl
空闲实验环境中的输出显示 NTP service 为 active 。要使用
timedatectl
手动调整日期和时间设置,必须先禁用此设置。 -
禁用 NTP 同步。
sudo timedatectl set-ntp no
-
设置日期和时间。
sudo timedatectl set-time '2014-09-23 14:10:40'
-
检查日期和时间。
date
-
获取时区的列表。
timedatectl list-timezones
按
q
可退出timedatectl
命令。 -
设置时区。
sudo timedatectl set-timezone 'America/Chicago'
-
检查新时区。
timedatectl
-
将时区返回到协调世界时 (Coordinated Universal Time,UTC)。
sudo timedatectl set-timezone 'UTC'
-
启用 NTP 同步。
sudo timedatectl set-ntp yes
一段时间后,将发生同步,并且时钟将根据时区集返回到当前日期和时间。
使用 Chrony
chrony 是 Oracle Linux 的一项功能,它实施 NTP 以在网络上准确维护计时,由 chronyd
和 chronyc
这两个组件组成。chronyd
是服务守护进程,可以在引导时启用和启动,而 chronyc
是用于监视 chronyd
性能和修改其运行时参数的命令行实用程序。
-
检查是否已安装 chrony 。
dnf list chrony
如果发现未安装,可以使用
sudo dnf install -y chrony
安装它。 -
检查服务守护进程的状态。
sudo systemctl status chronyd
如果服务处于非活动状态,则使用
sudo systemctl enable --now chronyd
启用并启动服务。按q
可退出systemctl
命令。 -
获取有关系统时钟性能的信息。
chronyc -n tracking
输出示例:
Reference ID : A9FEA9FE (169.254.169.254) Stratum : 3 Ref time (UTC) : Mon Feb 03 16:07:59 2025 System time : 0.000009410 seconds slow of NTP time Last offset : -0.000011537 seconds RMS offset : 0.000015202 seconds Frequency : 22.818 ppm slow Residual freq : -0.004 ppm Skew : 0.222 ppm Root delay : 0.000643811 seconds Root dispersion : 0.000107666 seconds Update interval : 64.4 seconds Leap status : Normal
其中:
- 参考 ID:这是计算机当前同步到的服务器的参考 ID 和名称或 IP 地址。输出中的引用 ID 显示为十六进制数字。
- 分层:分层表示此系统与具有附加参考时钟的计算机之间的跃点数。
- 参考时间:这是系统从参考来源处理最后一次测量时以 UTC 表示的时间。
通过使用
man chronyc
检查手册页,可以获得其他信息。 -
获取系统使用的源列表。
chronyc -n sources
使用
-v
选项可显示所显示每个列的列说明。
调度任务
Oracle Linux 包含多种调度任务的方法,这些任务或作业可以在系统或用户级别运行。虽然 cron 可能是这些方法中最著名的,但 systemd 在日历和单调时间的调度方面引入了更灵活的 timers ,并且它的使用越来越广泛。当前 Oracle Linux 发行版具有这两种功能的组合。
使用 Cron
-
检查系统级 cron 作业。
sudo ls -al /etc/cron*
输出提供了多个包含可执行脚本的目录,这些可执行脚本根据预定的调度执行选择任务,例如,每小时、每周和每月。
/etc/cron.d
目录也存在,软件包可以在不修改系统/etc/crontab
的情况下放置 crontab 片段。 -
获取系统级 cron 作业的列表。
sudo crontab -l
输出指示不存在适用于 root 的 crontab。在不使用
sudo
的情况下运行相同的命令会提供相同的输出,但对于本地用户帐户会提供相同的输出。 -
创建用户级 cron 作业。
(crontab -l 2>/dev/null; echo '* * * * * date >> /home/oracle/test') | crontab -
第一个命令可避免 no crontab 消息,因为这是输入的第一个作业,第二个命令将创建每分钟运行的作业。
-
验证 crontab 现在是否存在。
crontab -l
每个作业都显示在 crontab 中的独立行上。crontab 有五个空格分隔的字段,用于定义您可以配置的不同时段,后跟作业将运行的命令。该命令可以等效于可以在系统上的命令行上运行的任何命令,从而允许您运行脚本或利用管道和重定向运算符。如果要编辑作业,请使用
crontab -e
命令,该命令会将您拖到 Oracle Linux 上的默认 EDITORvi
中。Crontab 时间序列选项
Crontab 将时间字段定义为:
- 分钟:从 0 到 59
- 小时:从 0 到 23
- 日:从 1 到 31
- 月份:从 1 到 12,或月份的名称
- Day-of-week:从 0 到 7,或当天的缩写名称。请注意,0 和 7 都代表星期日。
您可以在任何时间字段中使用特殊字符:
- 星号 (*):指定应该为字段的每个实例运行该命令。
- 连字符 (-):可用于指示范围。例如,在“星期几”字段中,可以指定 1-5 将任务安排在星期一到星期五运行,但不要在星期六或星期日运行。
- 逗号 (,):可用于指定字段的值列表。例如,在小时字段中,您可以指定 6,18 以将任务安排在上午 6 点和下午 6 点运行。
- 正斜杠 (/):这可用于指定步骤值。例如,您可以在“分钟”字段中指定 */15,以安排每 15 分钟运行一次任务。
crontab 还允许您使用唯一的速记扩展来替换时间字段以满足一般时间要求。重要的是,此简写还包含一个在重新引导后运行命令的选项:
- @reboot:重新引导后运行一次。
- @yearly :每年运行一次,即“0 0 1 1 *”。
- @annually :每年运行一次,即“0 0 1 1 *”。
- @monthly :每月运行一次,即“0 0 1 * *”。
- @weekly :每周运行一次,即“0 0 * 0”。
- @daily :每天运行一次,即“0 0 * * *”。
- @hourly :每小时运行一次,即 "0 * * * *"。
crontab 仅提供 1 分钟的粒度。如果您需要对任务进行更细粒度的控制,建议您使用 systemd 计时器。
示例:
*/15 * * * * echo "This crontab entry runs every 15 minutes" 10 * * * * echo "This crontab entry runs at 10 minutes past every hour" 30 13 * * 3 echo "This crontab entry runs at 13h30 on every Wednesday" @reboot echo "This command runs once after a reboot event"
-
检查 cron 输出。
sudo tail /var/log/cron
输出显示运行日期、时间、用户和命令。由于默认的最小 Oracle Linux 安装不安装邮件传输代理 (Mail Transport Agent,MTA),因此 cron 守护进程会将 crontab 中指定的命令的输出定向到 Syslog 守护进程。因此,您可以在
/var/log/cron
处的日志文件中查看 crontab 输出。Crontab 命令语法
crontab 在 crontab 属于的用户凭证下运行,并在设置了一些默认环境变量的情况下运行,包括:
- HOME:crontab 运行为的用户的起始目录
- LOGNAME:等效于 crontab 作为其运行的用户的用户名
- USER:crontab 作为其运行的用户的用户名
- SHELL:系统用于运行命令的 SHELL 二进制文件。默认情况下,此值设置为
/bin/sh
。 - PATH:crontab 实用程序可用的路径。默认情况下,此值设置为
/usr/bin:/bin
。
您可以通过将替代环境变量指定为 crontab 中不包括时间字段的行来设置替代环境变量。例如,如果您希望使用 bash shell,并且希望定期导入个人
.bashrc
配置中的所有变量和设置,则可以使用crontab -e
编辑 crontab,如下所示:SHELL=/bin/bash * * * * * source $HOME/.bashrc;
由于 crontab 作业的命令在 shell 环境中运行,因此标准 shell 语法适用,并可用于管道输出或重定向输出。例如,要将所有输出重定向到 /dev/null,请在命令上对 STDOUT 和 STDERR 输出使用标准 shell 重定向:
* * * * * /path/to/command > /dev/null 2>&1
或者,您可以重定向输出以附加到文件,每次运行命令时可以使用该文件跟踪输出:
* * * * * /path/to/command >> $HOME/command.log
示例:
*/15 * * * * echo "This 'silent' crontab entry runs every 15 minutes but the output is redirected to /dev/null" > /dev/null 2>&1 * * * * * echo "The date and time is $(date +\%Y-\%m-\%d\ \%H:\%M:\%S)" >> $HOME/crontab.log
该示例对 date 命令中的
%
字符进行转义,因为 crontab 实用程序将%
字符更改为换行符,并将第一个%
之后的所有数据作为标准输入发送到命令。有关更多信息,请参见man 5 crontab
。
删除 Crontab 文件
如果仅计划删除特定作业,则可以使用 crontab -e
命令编辑和删除包含该作业的单个行。但是,如果要删除所有作业,crontab
提供了一个快速高效的选项。
-
删除所有 cron 作业条目。
crontab -r
Systemd 计时器
与 cron 作业一样,systemd 计时器允许在特定时间运行命令或脚本。但是,这些任务由 systemd 控制和监督,并且对基于时间的激活进行了更精细的控制。
-
列出现有计时器。
systemctl status *timer
按
q
可退出systemctl
命令。
创建计时器
计时器由一个服务单元组成,该服务单元定义要执行的工作,以及一个计时器单元来调度和触发它。由于这些是 systemd 服务单元,因此可以在系统或用户空间中创建它们。用户空间的好处是,它允许用户管理他们的服务,如守护程序和自动化任务。
-
创建本地用户的 systemd 目录。
mkdir -p ~/.config/systemd/user
系统级服务单元和计时器进入
/etc/systemd/system
。 -
为当前用户启用持久性。
loginctl enable-linger $(whoami)
逗留是指 systemd 中的一项功能,允许用户进程即使在用户注销其会话后仍继续运行。
-
验证用户的滞后状态。
loginctl user-status $(whoami)
按
q
可退出 loginctl 命令。 -
编写供计时器运行的脚本。
cat << 'EOF' | tee ~/test.sh > /dev/null #!/bin/bash /usr/bin/echo "test from test.service: $(date)" 2>&1 | tee -a /home/oracle/test.log EOF
-
将脚本设置为可执行。
chmod +x ~/test.sh
-
创建服务单位。
cat << EOF | tee ~/.config/systemd/user/test.service > /dev/null [Unit] Description=Run the test script StartLimitIntervalSec=1 StartLimitBurst=10 [Service] Type=oneshot ExecStart=/home/oracle/test.sh StandardOutput=journal SyslogIdentifier=test EOF
该服务需要
StartLimitIntervalSec
和StartLimitBurst
,因为它打算每隔几秒运行一次此服务。您可以在man systemd.unit
中了解有关这些参数的更多信息。 -
创建计时器单元。
cat << EOF | tee ~/.config/systemd/user/test.timer > /dev/null [Unit] Description=Run test.service every 10 seconds [Timer] OnCalendar=*:*:0/10 AccuracySec=1 Persistent=true [Install] WantedBy=timers.target EOF
AccuracySec
参数是必需的,因为 systemd 计时器在请求时不完全执行,而是对一分钟的默认方差进行操作。 -
让 systemd 知道这些更改。
systemctl --user daemon-reload
-
启用和启动计时器。
systemctl --user enable --now test.timer
-
验证计时器是否正在运行。
systemctl --user status test.timer --no-pager
--no-pager
选项打印完整输出,而无需滚动或翻页。有关其他选项,请查看systemctl --help
。 -
检查 bash 脚本的日志文件。
cat ~/test.log
-
检查 systemd 日记帐。
journalctl -r -n 10 --user-unit test --no-pager
此输出显示用户 test.service systemd 单元的最后 10 行输出。
-r
选项按逆时间顺序显示日记账分录。journalctl -r -n 10 -t test --no-pager
此命令显示由 systemd 服务单元运行的脚本生成的输出。
-t
选项与test.service
文件中定义的SyslogIdentifier
匹配,该文件提供要搜索的标识符。通过阅读man journalctl
页面查看journalctl
的更多选项。 -
禁用计时器。
systemctl --user disable test.timer
此命令可防止计时器将来自动启动并使其处于非活动状态。
-
停止计时器。
systemctl --user stop test.timer
如果计时器正在运行,此命令将停止该计时器的当前执行。它不会阻止计时器在未来再次启动。
后续步骤
完成本教程后,您将掌握在 Oracle Linux 上管理日期、时间和安排任务的技能和能力。显示的命令还有许多其他标志和功能。请查看下面的链接以及建议的手册页,以提高您的知识和技能。
相关链接
更多学习资源
通过 docs.oracle.com/learn 浏览其他实验室,或者通过 Oracle Learning YouTube 频道访问更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 以成为 Oracle Learning Explorer。
有关产品文档,请访问 Oracle 帮助中心。