如何在运行 60 分钟后关闭 Linux 服务器?

jmh*_*let 18 shutdown cron

我有一台服务器,出于安全原因,它通常会关闭。当我想处理它时,我打开它,执行我的任务,然后再次关闭它。我的任务通常不超过 15 分钟。我想实现一种在 60 分钟后自动关闭它的机制。

我已经研究过如何用 cron 做到这一点,但我认为这不是正确的方法,因为 cron 没有考虑上次打开服务器的时间。我只能设置周期性模式,但他们不考虑这些数据。

我怎么能做这个实现?

seb*_*sth 69

有几个选项。

对于后两种方法,您还可以使用sleep 3600 && shutdown -P now而不是使用时间参数shutdown来延迟 60 分钟的关闭。这样就可以登录到发出关机前的最后一刻。

  • 我认为使用 `sleep` 命令,你仍然需要指定一个时间来 `shutdown` - 如果我们已经完成了等待,我们希望使用 `now` 作为该参数(但请注意,你不会得到非常警告,在您的作品从您身下消失之前保存您的作品!)。 (2认同)

Lie*_*yan 32

这看起来像是一个XY 问题

我的任务通常不超过 15 分钟。我想实现一种在 60 分钟后自动关闭它的机制。

如果您在 60 分钟后关闭,您将面临运行一个特别复杂的问题并且只需要更多时间的风险。以前的许多解决方案都无法轻松延迟关机。

如果任务不是交互式任务,而是从另一台机器自动触发的脚本任务,@sdkks 对此给出了很好的解决方案;您真的应该让机器在脚本及其所有任务完成后立即运行 poweroff。

但是,如果您的任务是交互式任务,我建议改为进行空闲检测。

如果您在 GUI (X11) 中执行任务,您可以使用此处描述的方法检测空闲的 GUI 会话:当系统空闲时运行命令,何时再次处于活动状态

如果您通过终端执行任务,则可以使用该who命令检测已登录的用户。您可以设置一个 cronjob,如果who返回空结果则关闭机器。请注意,这将是一种相当保守的方法;如果您将控制台保持连接但空闲,它不会关闭系统。

如果您还想更积极一点并断开空闲终端会话,您可以将之前的方法与自动断开空闲 SSH 会话 ClientAliveIntervalClientAliveCountMax. 如果您没有 SSH,但有本地终端会话,另一种方法是使用命令返回的终端空闲时间w

  • 这是非常重要的一点。无论您实施什么 - 确保您也可以*取消*关闭符合您的利益。 (2认同)

Dir*_*man 23

如果您每次都以同一用户身份执行任务,则只需将关闭命令(可选地使用选项 -P)添加到您的配置文件中即可。该数字代表关闭命令延迟的分钟数。确保您的用户能够在没有密码的情况下通过 sudo 执行关闭命令。

echo "sudo shutdown -P +60" >> ~/.profile
Run Code Online (Sandbox Code Playgroud)

添加:

在阅读了大多数其他答案后,我喜欢在(root)cron 中添加“@reboot /<path to script/command>”的选项。sebasth 给出的答案是他的第四个选项。您可以添加关闭命令或编写一个执行关闭并通过 cron 执行的小脚本。如果你使用 systemd,WoJ 也有一个很好的解决方案。

  • 我想每次 ssh 登录都会导致新的关机调用。那么计数器会重置吗? (17认同)
  • 但是请先尝试该命令一次,您不希望将即时关机绑定到您的配置文件! (12认同)
  • 时间以分钟为单位,而不是秒。尝试 `shutdown -k -P 3600` 与 `shutdown -k -P 60`(`-k` 打印墙消息但没有其他效果) (11认同)
  • 请注意,登录后 60 分钟与启动后 60 分钟不同。如果您启动机器然后忘记登录怎么办? (7认同)
  • 值得一提的是,如关闭手册中所述,在最后 5 分钟内不允许登录。 (4认同)
  • @JoL - 是的。基于对 `shutdown` 的一些试验和检查 `/run/systemd/shutdown/scheduled` 中的时间,似乎最后的 `shutdown` 命令覆盖了所有先前的 `shutdown`,无论新时间是早还是早比上次晚。所以这个解决方案会在_last_登录后3600分钟关闭系统,而不是_first_登录后3600分钟。 (2认同)

小智 8

虽然这里之前的回答都满足完美的要求,但是你也可以在任务完成后立即关闭你的机器。

bash脚本可以被trapped,这意味着可以拦截某些信号,并且可以在需要时执行某些任务。EXIT是可以被捕获的信号之一。

您将能够:

  1. trapEXIT你的自动化 shell 脚本设置一个for ,这意味着你的自动化任务的终止
  2. trap为您的设置一个.bashrc EXIT,这意味着每当您退出该机器时,将其关闭。

如果您的任务不需要临时检查和手动判断,则选项 #1 将是理想的情况。

选项#2 将涵盖您忘记退出终端而不关闭电源的情况。不过有一个警告;如果您打开同一台机器的多个终端,然后从其中一个终端退出,它仍然会关闭机器的电源。(可以编写脚本来避免这种情况,但我不会使解决方案复杂化。)

cleanup(){
    # Do some tasks before terminating
    echo oh la la, cleaning is so nice
    echo "See you later, world"
    sudo poweroff & # finally shutdown
}
trap cleanup EXIT
Run Code Online (Sandbox Code Playgroud)

这可以在.bashrc选项 #2的末尾,在选项 #1 的脚本顶部的某个位置。

为什么不在poweroff脚本末尾使用?

我更喜欢set -eo pipefail在我的脚本顶部使用at 。如果发生任何错误,它不会静默失败;它将停止执行更多命令。trapEXIT信号应当覆盖脚本过早终止由于错误的案件。

但是,对于您的任务,这也可能意味着机器将在完成之前关闭。

我有一个简单的bash模板,用于使脚本更易于调试;也许它可能有一些用处。请参阅此要点


Cri*_*gie 5

下面command带参数运行,如果它成功完成,它会立即关闭框,假设用户可以运行poweroff. 它可能需要使用sudo poweroff.

command --parameters && poweroff
Run Code Online (Sandbox Code Playgroud)

而以下poweroff命令会在命令终止时立即运行:

command --parameters ; poweroff
Run Code Online (Sandbox Code Playgroud)

如果您认为命令完成后需要休息时间,请运行

command --parameters ; sleep 3600 ; poweroff
Run Code Online (Sandbox Code Playgroud)

如果您认为该命令可能会超时运行,您可以将其限制为一个小时:

timeout 1h command --parameters ; poweroff
Run Code Online (Sandbox Code Playgroud)

timeoutcoreutils软件包的一部分,因此您可能已经拥有它。