我有一台服务器,出于安全原因,它通常会关闭。当我想处理它时,我打开它,执行我的任务,然后再次关闭它。我的任务通常不超过 15 分钟。我想实现一种在 60 分钟后自动关闭它的机制。
我已经研究过如何用 cron 做到这一点,但我认为这不是正确的方法,因为 cron 没有考虑上次打开服务器的时间。我只能设置周期性模式,但他们不考虑这些数据。
我怎么能做这个实现?
seb*_*sth 69
有几个选项。
直接提供时间给shutdown -P
:
shutdown -P +60
Run Code Online (Sandbox Code Playgroud)
请注意,shutdown
手册页还指出:
如果使用时间参数,则在系统关闭前 5 分钟创建 /run/nologin 文件以确保不允许进一步登录。
使用at
命令。
创建在启动时运行的systemd 单元文件或初始化脚本shutdown -P 60
。
@reboot
启动后使用 cron运行命令。
添加到(根)crontab:
@reboot shutdown -P +60
Run Code Online (Sandbox Code Playgroud)对于后两种方法,您还可以使用sleep 3600 && shutdown -P now
而不是使用时间参数shutdown
来延迟 60 分钟的关闭。这样就可以登录到发出关机前的最后一刻。
Lie*_*yan 32
这看起来像是一个XY 问题。
我的任务通常不超过 15 分钟。我想实现一种在 60 分钟后自动关闭它的机制。
如果您在 60 分钟后关闭,您将面临运行一个特别复杂的问题并且只需要更多时间的风险。以前的许多解决方案都无法轻松延迟关机。
如果任务不是交互式任务,而是从另一台机器自动触发的脚本任务,@sdkks 对此给出了很好的解决方案;您真的应该让机器在脚本及其所有任务完成后立即运行 poweroff。
但是,如果您的任务是交互式任务,我建议改为进行空闲检测。
如果您在 GUI (X11) 中执行任务,您可以使用此处描述的方法检测空闲的 GUI 会话:当系统空闲时运行命令,何时再次处于活动状态
如果您通过终端执行任务,则可以使用该who
命令检测已登录的用户。您可以设置一个 cronjob,如果who
返回空结果则关闭机器。请注意,这将是一种相当保守的方法;如果您将控制台保持连接但空闲,它不会关闭系统。
如果您还想更积极一点并断开空闲终端会话,您可以将之前的方法与自动断开空闲 SSH 会话 ClientAliveInterval
和ClientAliveCountMax
. 如果您没有 SSH,但有本地终端会话,另一种方法是使用命令返回的终端空闲时间w
。
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 也有一个很好的解决方案。
小智 8
虽然这里之前的回答都满足完美的要求,但是你也可以在任务完成后立即关闭你的机器。
bash
脚本可以被trap
ped,这意味着可以拦截某些信号,并且可以在需要时执行某些任务。EXIT
是可以被捕获的信号之一。
您将能够:
trap
为EXIT
你的自动化 shell 脚本设置一个for ,这意味着你的自动化任务的终止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 。如果发生任何错误,它不会静默失败;它将停止执行更多命令。trap
的EXIT
信号应当覆盖脚本过早终止由于错误的案件。
但是,对于您的任务,这也可能意味着机器将在完成之前关闭。
我有一个简单的bash
模板,用于使脚本更易于调试;也许它可能有一些用处。请参阅此要点。
下面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)
timeout
是coreutils
软件包的一部分,因此您可能已经拥有它。