[疑问]如何使用 cron 让脚本每 7 分钟执行一次?

2024-05-30 16:47:00 +08:00
 wuyadaxian
我的环境是 Ubuntu 22.04LTS 。
要求是从现在或者某个时间点开始,每 7 分钟执行一次 test.sh 脚本。
只能使用 crontab 来编写。
只是讨论,真正实现的时候肯定用 bash 或者其他语言脚本更方便实现。
18952 次点击
所在节点    程序员
162 条回复
honjow
2024-05-31 23:44:55 +08:00
@Felldeadbird #124 能跑啊。。。只是不能整除的话,最后一次间隔就不对啊
w568w
2024-06-01 00:12:10 +08:00
@mingwiki 必须纠正一个误区:systemd 可能确实看起来功能很多,但毕竟是用 C 写的,实际上是非常轻量的:本身完全体只占用不到 10MB 内存、CPU 占用接近 0 。OpenRC 之类靠 Shell 程序的解决方案,怎么做都不如 C 性能高、占用小、功耗低。如果只看占用和功能,实际上服务和需求多起来,OpenRC 占不到多少便宜,对服务的控制力度还小得多。

大部分人还是由于对 systemd 的学习曲线望而却步或者不认同 systemd 的设计,所以认为 systemd 臃肿。但就楼主这个需求,systemd timer 应该是最简单、轻量的解决方案。
BraveXaiver
2024-06-01 00:13:46 +08:00
题主现在有结论了不?可以 append 一下吗?
lolizeppelin
2024-06-01 00:24:07 +08:00
在 cron 里绕来绕去
用 6 整除。脚本里根据启动时间 sleep 到 7 分钟
周期一 sleep 60
周期二 sleep 120
第六周期直接跳过
james122333
2024-06-01 00:40:09 +08:00
@w568w

早就破 30MB 了好吗 压缩的不是真实大小
openrc... 2MB 以内 算上额外脚本包也多不了多少 systemd 要做那么多事早就注定它小不了
运行的东西多怎能期待它能占用小 很多东西都不是很必要 它提供的特性说实话我都用不到 很多东西我都可以直接写脚本解决 运行效率也不低 只要你会写 这种东西就不是给你组装使用的 灵活与扩充性降低 unix 哲学好在我能够用原生工具凑出我要的东西 而不用上游没出下游不用想 也不用整天在找工具 而且你太小看脚本了
james122333
2024-06-01 00:45:37 +08:00
@w568w

再给你个看法 一个东西能性能高占用小 语言只是其中一个因素 很多时后更重要的还是在于你怎么写
james122333
2024-06-01 00:47:04 +08:00
@w568w

C 语言上限高不代表用 C 写的都是好货
w568w
2024-06-01 01:02:15 +08:00
@james122333 #147

> 早就破 30MB 了好吗 压缩的不是真实大小……openrc... 2MB 以内 算上额外脚本包也多不了多少

我认为你和我说的根本不是一件事:我说的是 RAM 占用,你说的是安装后的文件体积。

---

> systemd 要做那么多事早就注定它小不了 运行的东西多怎能期待它能占用小
> C 语言上限高不代表用 C 写的都是好货

「注定它小不了」的数字和证据,来源请求?请勿脑测程序性能。我用你后一句的原话返还:要做的事情多不代表占用大、组合性好不代表占用小。

---

> unix 哲学好在我能够用原生工具凑出我要的东西 而不用上游没出下游不用想

是的,Systemd 和 Unix 哲学有冲突,但正如我说的,很多人不喜欢 Systemd 就是因为它的设计。KISS 和 All in one 本来就是有分歧的。但在服务调度和管理这件事上,我站 systemd 这边。

我没有一棒子打死 Shell ,只是认为应该给 systemd 正名。毕竟「污名化」「虚无化」 systemd 的声音太多,会给 Linux 萌新错误的第一印象。

---

> 你太小看脚本了

我哪里说脚本不好了?我的原话是:「就楼主这个需求,systemd timer 应该是最简单、轻量的解决方案」。你说的和我的回复有关系?

---

> 再给你个看法 一个东西能性能高占用小 语言只是其中一个因素 很多时后更重要的还是在于你怎么写

你也知道只是个「看法」了,那我没啥好说的。就 C 和 Shell 的性能问题,我相信你心里有杆秤:你要硬说 Shell 就是能在服务管理的性能、功能和占用上替代 C ,我也没办法。我只知道嵌入式 Linux 很多都开始回归 systemd 了,我的印象里,16MB RAM 的板上系统跑裁剪版的 systemd 没有压力。
w568w
2024-06-01 01:14:43 +08:00
提供一个 Systemd timer 的解法,在 /etc/systemd/system 下分别新建 myscript.service 和 myscript.timer 两个文件,填写以下内容:

myscript.service:

[Service]
Type=simple
ExecStart=/path/to/myscript.sh

myscript.timer:

[Timer]
Unit=myscript.service
OnUnitActiveSec=7m

[Install]
WantedBy=timers.target

然后 sudo systemctl daemon-reload && sudo systemctl enable --now myscript.timer 。结束。

以上内容手敲,不保证对。
james122333
2024-06-01 01:31:15 +08:00
@w568w

ram 占用也是一样的 systemd 主进程不算 还有很多子进程 要一并算在内
还脑测程序性能... 我要额外装 systemd 再给你看证据? 证据自取好吗 做的事多占用大是正比 你能减低占用但占用还是会上升 依照 systemd 做的事情我不觉得这是很值得的 我宁愿组合性高并一样设法降低占用 如果你以上一堆人写脚本方式推估当然是效能差
systemd 除了违背哲学以外还有 bug 以及漏洞问题 不是因为它只是违背哲学 而被视为污泥正是历史事件一步一步来的 以我所见相反 初学者反而觉得 systemd 好 而历史他们也不会知道 只有在这环境打滚久的会觉得 systemd 是垃圾
"你太小看脚本"不正是你说的怎么做都不如 C 写的吗?两者相比也并不能以单方面来看
至于 systemd timer 我看来还不如 cron
换技术不会只有效能考量 你可以说 c 写的好的效能好过其它 但写的差的你也没讲 讲这种话我是觉得你应该不是开发 C 绝对好也是种暴论 而根据使用经验 效能也体验不出来的
w568w
2024-06-01 01:47:25 +08:00
@james122333 #150

> ram 占用也是一样的 systemd 主进程不算 还有很多子进程 要一并算在内

我看了一下我的桌面端占用:一个 systemd 10MB ,一个 systemd user 进程 8.4MB 。还有什么「起服务调度作用」的「子进程」?

另外注意比较公平:如果你认为 systemd-journald 、oomd 、resolved 等 systemd 模块也算 systemd 的一部分,那么请在计算 OpenRC 的占用时,把对应的进程也加上。毕竟 systemd 系统上是不需要那些进程的。

---

> 还脑测程序性能 ... 我要额外装 systemd 再给你看证据?

而我确实是有安装了 OpenRC 和 systemd 的服务器的,systemd 还是装在树莓派上的那个。需要我贴图给你比较两边的占用吗?我的结论是:两边占用差距不大,甚至 systemd 这边更小。

---

> systemd 除了违背哲学以外还有 bug 以及漏洞问题

??你推崇的 Shell 没有 bug 和漏洞问题?

---

> 只有在这环境打滚久的会觉得 systemd 是垃圾
> 根据使用经验 效能也体验不出来的

比资历和经验就没意思了,那你说得都对。

---

> 但写的差的你也没讲

systemd 是你说的「写的差」的吗?

---

> 讲这种话我是觉得你应该不是开发 C

我还真是写过 C 的,而且主要就是嵌入式。另外「我写没写过 C 、有几年经验」和我的回复对不对有什么关系?

还是那句话,程序员用数据说话。不贴数据猛贴资历,那我没话说了,你说的都对。

---

> 至于 systemd timer 我看来还不如 cron

说了半天终于回主题上了,然而也没给任何证据,就一句「 xx 不如 yy 」。同上,不知道你想说什么。
james122333
2024-06-01 02:09:37 +08:00
@w568w

当然算在内 那些进程说实话用处都不大 openrc 也并不会主动帮你开服务 与 systemd 因应情况启动程序不同 有些发行版甚至还会主动帮你启动一些东西
那你情况很特殊 我的使用情况是用小型 init 的占用都是极低 除非我开一些重量级应用直接盖过去
shell 当然可能会有漏洞 但 systemd 影响层面高过 shell 太多 而 shell 写的本身也有一定隔离效果 除非恶搞乱写 而 shell 也很多 一个有漏洞换掉即可
没在比资历 是看不懂是在科普是吗 其它人接不接受是另外一回事
systemd 当然是属于写的差的 不是我一个人在讲
我没填标点符号 C 开头那是另外一句 证据你有提供出来吗 讲证据是不是搞笑
james122333
2024-06-01 02:16:53 +08:00
@w568w

以纯设置来讲 cron 好过 systemd timer
以哲学来讲 cron 是个别工具
以效能来讲请补充
skinny
2024-06-01 08:45:25 +08:00
既然不能可靠的每 7 分钟运行一次,那每分钟检查一次,保留最后一次运行时间,如果要确保只有一个实例就保存 PID 。这就是一种比较普遍可靠的方法。

记录保存:
/var/<mytask>/last_execute_time
/var/<mytask>/<mytask>.pid

程序基本逻辑就是先检查有没有其它实例在运行,然后检查当前时间和上次执行时间差。运行时保存时间戳和 PID 。
idigital
2024-06-01 09:03:39 +08:00
试试 gpt 的回答
要使用 `cron` 调度器在 Unix/Linux 系统中每 7 分钟执行一次脚本,可以通过以下步骤实现:

1. **打开 Crontab 编辑器**:
使用以下命令打开 crontab 文件进行编辑。`crontab` 是用户级任务计划文件,可以使用以下命令来编辑当前用户的 crontab:

```bash
crontab -e
```

2. **添加 Crontab 任务**:
在 crontab 编辑器中添加以下行,表示每 7 分钟执行一次某个脚本。假设你的脚本在 `/path/to/your_script.sh`:

```cron
*/7 * * * * /path/to/your_script.sh
```

这里,`*/7` 表示每 7 分钟执行一次任务。

3. **保存并退出编辑器**:
保存编辑并退出(具体的保存方式因不同的文本编辑器而异,例如在 `vim` 编辑器中是 `:wq`)。

4. **确保脚本可执行**:
确保你的脚本具有执行权限。如果没有,使用以下命令赋予可执行权限:

```bash
chmod +x /path/to/your_script.sh
```

例子解释:
- `*/7 * * * *`:每 7 分钟执行一次任务。
- 前一个星号 `*` 表示分钟的占位符。
- 这里的 `/7` 表示每 7 分钟执行一次。
- 其他的星号 `*` 分别代表小时、日期、月份和星期几,而它们保持星号代表任何时间。

这样设置以后,cron 会根据定义的时间间隔每 7 分钟执行一次指定的脚本。

### 其它注意事项

1. **查看 cron 日志**:
如果你想要确认 cron 是否在按预期执行脚本,可以查看系统的 cron 日志。日志文件位置因系统配置而异,但一般为 `/var/log/cron` 或 `/var/log/syslog`。

在某些系统中可能需要超级用户权限来查看这些日志,因此可以使用以下命令:

```bash
sudo tail -f /var/log/cron
```

或者

```bash
sudo tail -f /var/log/syslog
```

2. **检查 cron 任务**:
如果要验证当前用户的 crontab ,包括编辑或列出已有的任务,可以使用以下命令列出任务:

```bash
crontab -l
```

通过这些步骤,你应该能够成功配置 cron 以每 7 分钟运行一次你的脚本。
wuyadaxian
2024-06-01 12:16:56 +08:00
@yankebupt 不会超过 60 分钟或 24 小时。
3/7 2/7 * * 3 command
是很好的缩写。
wuyadaxian
2024-06-01 12:23:34 +08:00
@BraveXaiver append 了。感谢提醒。
fqzz
2024-06-02 14:23:23 +08:00
换成 systemd timer 吧,cron 这么玩太折腾了
huangzhiyia
2024-06-03 12:52:05 +08:00
value=$(echo $(( ($(cat /tmp/1045433_time 2>/dev/null || echo 0) + 1) % 7 )) > /tmp/1045433_time && cat /tmp/1045433_time) && [ "$value" -eq 0 ] && your_command_here
huangzhiyia
2024-06-03 12:58:36 +08:00
上面每分钟执行一次就行了,第一次就会运行并输出到 0 ,每次运行命令后文件里的值执行以下逻辑:

v=(v+1) % 7

然后判断 v 是否等于 0 ,是的话就执行 your_command_here 命令。

这个命令放在 crontab 可能会有点问题,可能需要加绝对路径以及对特殊的符合进行转义。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1045433

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX