systemd已经提供了一段时间的计时器,取代了cron功能,这个功能值得一看。本文将向您展示如何在systemd中使用计时器在系统启动后运行任务,并在之后重复运行它们。这不是对systemd的全面讨论,只是对该功能的介绍。快速回顾:cron、anacron和systemdcron可以安排作业以几分钟到几个月或更长时间的粒度运行。设置起来比较简单,只需要一个配置文件。虽然配置过程有些深奥,但一般用户都可以使用。但是,如果您的系统在需要执行时没有运行,cron将会失败。anacron克服了“系统未运行”的问题。它确保当您的系统再次启动时将执行该任务。虽然它是供管理员使用的,但某些系统允许普通用户访问anacron。但是,anacron的执行频率不能低于每天一次。cron和anacron都存在执行上下文一致性的问题。必须注意,任务实际运行的环境与测试它的环境完全相同。必须提供相同的shell、环境变量和路径。这意味着测试和调试有时会很困难。systemd计时器提供了cron和anacron的优点,允许将调度细化到分钟粒度。确保在系统再次运行时执行任务,即使系统在预期执行时间内关闭也是如此。它对所有用户可用。你可以在它运行的环境中测试和调试执行。但是它的配置比较复杂,至少需要两个配置文件。如果您的cron和anacron配置很好地为您服务,则可能没有理由更改。但systemd至少值得研究,因为它可以简化任何当前的cron/anacron做事方式。配置systemd定时器执行至少需要两个文件。这两个是“定时器单元timerunit”和“serviceunit服务单元”。“动作”不仅仅是简单的命令,你还需要一个“作业”文件或脚本来执行必要的功能。计时器单元文件定义了时间表,而服务单元文件定义了要执行的任务。有关详细信息,请参阅mansystemd.timer中提供的.timer单元。服务单元的详细信息可以在mansystemd.service中找到。单元文件存储在几个位置(在手册页中列出)。然而,对于普通用户来说,最容易找到的位置可能是~/.config/systemd/user。请注意,这里的用户是字符串用户。示例此示例是创建用户计划作业而不是系统计划作业(以root身份运行)的简单示例。它将消息、日期和时间打印到文件中。1.首先创建一个shell脚本来执行任务。在本地bin目录中创建它,例如在~/bin/schedule-test.sh中。创建文件:touch~/bin/schedule-test.sh然后将以下内容添加到刚刚创建的文件中:#!/bin/shecho"Thisisonlyatest:$(date)">>"$HOME/schedule-test-output.txt”记得给你的shell脚本执行权限。2.创建一个.service单元来调用上面的脚本。在以下位置创建目录和文件:~/.config/systemd/user/schedule-test.service:[Unit]Description=Ajobtotestthesystemdscheduler[Service]Type=simpleExecStart=/home//bin/schedule-test.sh[Install]WantedBy=default.target请注意,应该是你家目录的地址,但单元文件路径名中的user实际上是字符串user。ExecStart应该提供一个没有变量的绝对地址。例外情况是对于用户单元文件,您可以将$HOME替换为%h。也就是说,可以使用:ExecStart=%h/bin/schedule-test.sh这个只针对用户单元文件,不针对系统服务,因为%h在系统环境下运行总是返回/root。其他特殊符号可以在mansystemd.unit的SPECIFIERS中找到。由于它超出了本文的范围,所以我们现在需要了解的关于特殊符号的全部内容。3.创建一个.timer单元文件,它实际调度您创建的.service单元文件。在与.service单元文件相同的位置创建它:~/.config/systemd/user/schedule-test.timer。请注意,文件名仅在扩展名上有所不同,例如,一个是.service,一个是.timer。[Unit]Description=每1分钟安排一条消息RefuseManualStart=no#允许手动启动RefuseManualStop=no#允许手动停止[Timer]#如果由于机器关闭而错过运行则执行作业Persistent=true#第一次启动后运行120秒timeOnBootSec=120#Runevery1minuteafterafterOnUnitActiveSec=60#FiledescribingjobtoexecuteUnit=schedule-test.service[Install]WantedBy=timers.target请注意,此.timer单元文件使用OnUnitActiveSec来指定时间表。OnCalendar选项更灵活。例如:#在每天的每小时的每分钟的分钟运行OnCalendar=*-*-**:*:00#在每天的每小时的整点运行OnCalendar=*-*-**:00:00#每天运行OnCalendar=*-*-*00:00:00#在一年中任何一个月的第一天或第五天的11:12:13运行#2012,但前提是那一天是星期四或星期五OnCalendar=Thu,Fri2012-*-1,511:12:13可以在此处找到有关OnCalendar的更多信息。4.所有部件都已到位,但您应该进行测试以确保一切正常。首先,启用用户服务:$systemctl--userenableschedule-test.service这将导致输出类似于:Createdsymlink/home//.config/systemd/user/default.target.wants/schedule-test.service→/home//.config/systemd/user/schedule-test.service。现在执行测试作业:$systemctl--userstartschedule-test.service检查您的输出文件($HOME/schedule-test-output.txt)以确保您的脚本正常工作。应该只有一个条目,因为我们还没有启动计时器。必要时进行调试。如果您需要更改.service单元文件而不是它调用的shell脚本,请不要忘记再次启用该服务。5.作业正常运行后,通过为服务启用和启动用户计时器来实时安排作业:$systemctl--userenableschedule-test.timer$systemctl--userstartschedule-test.timer注意youarealreadyonit你在的第4步中启动并启用了该服务,因此你只需要为其启用并启动计时器即可。enable命令产生以下输出:Createdsymlink/home//.config/systemd/user/timers.target.wants/schedule-test.timer→/home//.config/systemd/user/schedule-test.timer.start命令将简单地返回到CLI提示符。您可以检查和监视服务的其他操作。如果系统服务出错,下面的第一个命令特别有用:$systemctl--userstatusschedule-test$systemctl--userlist-unit-files手动停止服务:$systemctl--userstopschedule-test.service永久停止和禁用计时器和服务,重新加载守护程序配置并重置任何失败通知:$systemctl--userstopschedule-test.timer$systemctl--userdisableschedule-test.timer$systemctl--userstopschedule-test.service$systemctl--userdisableschedule-test.service$systemctl--userdaemon-reload$systemctl--userreset-failed总结本文以systemd定时器为出发点,但systemd的内容远不止于此.这篇文章应该给你一个基础。您可以通过FedoraMagazinesystemd系列开始探索更多内容。