【问题标题】:How can I trigger a delayed system shutdown from in a shell script?如何在 shell 脚本中触发延迟的系统关闭?
【发布时间】:2013-11-18 11:42:51
【问题描述】:

在我的私人网络上,我有一个备份服务器,它每晚运行一次 bacula 备份。为了节省能源,我使用 cron 作业来唤醒服务器,但我还没有发现如何在备份完成后正确关闭它。 通过 bacula-director 配置,我可以在处理最后一个备份作业(即文件目录的备份)期间调用脚本。我尝试使用这个脚本:

#!/bin/bash
# shutdown server in 10 minutes
#
# ps, 17.11.2013
bash -c "nohup /sbin/shutdown -h 10" &
exit 0

脚本关闭服务器 - 但显然它只是在关闭期间返回, 因此,最后一个备份作业会一直挂起,直到关机。如何使脚本文件关闭并立即返回?

更新:经过广泛搜索后,我想出了一个(尽管很丑陋)的解决方案: bacula 运行的脚本如下所示:

#!/bin/bash
at -f /root/scripts/shutdown_now.sh now + 10 minutes

第二个脚本(shutdown_now.sh)看起来像这样:

#!/bin/bash
shutdown -h now

其实我没有发现明显的方法可以在'at'命令的语法中添加shutdown所需的参数。也许有人可以在这里给我一些建议。

【问题讨论】:

  • 刚刚在我的 Debian 机器上测试过,似乎还是正确的,虽然不需要将其包装到 bash -c 中,nohup /sbin/shutdown -h 10 & 似乎在这里工作得很好

标签: linux bash shell shutdown


【解决方案1】:

根据您的备份服务器的操作系统,shutdown 的实现可能会有不同的表现。我在 Ubuntu 12.04 上测试了以下两种解决方案,它们都对我有用:

作为 root 用户,我创建了一个包含以下内容的 shell 脚本并在 bash shell 中调用它:

shutdown -h 10 &
exit 0

shell 中脚本的退出代码是正确的(用echo $? 测试)。关机仍在进行中(使用shutdown -c 测试)。

第二个 shell 脚本中的这个 bash 函数调用同样有效:

my_shutdown() {
  shutdown -h 10
}
my_shutdown &
exit 0

【讨论】:

  • 感谢您的帮助!但不知何故,这似乎不足以让 bacula 相信脚本已成功完成。
  • 我可以想象你的备份脚本进程仍然是关闭进程的父进程——即使我们试图分叉它。 Bacula 然后注意到周围还有一些子进程并阻塞,直到关闭发生。在我的机器上,关机进程似乎是一个新进程;但这可能又取决于操作系统。您可以尝试更努力地“守护”您的关闭命令,如下所示:nohup shutdown -h 10 0<&- &>/dev/null & (via) 在我的机器上这似乎没有改变任何东西,但也许它对您有用。
  • 感谢您的建议。我会在接下来的几天里尝试一下。与此同时,我使用 at-scheduler,它也解决了这个问题。但由于我很好奇,我还是会测试你的建议。 PS:我用的是 Debian Jessie。
【解决方案2】:

无需创建第二个 BASH 脚本来运行关闭命令。只需替换备份脚本中的以下行:

bash -c "nohup /sbin/shutdown -h 10" &

用这个:

echo "/sbin/poweroff" | /usr/bin/at now + 10 min >/dev/null 2>&1

随意调整时间间隔以满足您的喜好。

【讨论】:

  • 这就像一个魅力。但是,我想知道您重定向 at 命令的输出的原因是什么。它是shell编程中的某种“最佳实践”吗?
  • 将诸如此类生成信息输出的命令放入自动化作业中有时会导致每次运行作业时都会发送电子邮件至 root。丢弃此类输出并阻止此类电子邮件只是我个人的偏好。当然,这确实意味着可能会丢失潜在的错误消息,因此也必须权衡这种可能性。
【解决方案3】:

如果你能成为 root:要么登录,要么sudo -i 这有效(在 ubuntu 14.04 上测试):

# shutdown -h 20:00 & //晚上 8 点停止机器

不需要 shell 脚本。然后我可以注销,然后重新登录,该过程仍然存在。有趣的是,如果我在命令行中使用sudo 尝试此操作,那么当我注销时,该进程就会消失!

顺便说一句,请注意,我也使用此命令在每个人都回家后偶尔重新启动。

# shutdown -r 20:00 & //晚上 8 点重启机器

【讨论】:

    猜你喜欢
    • 2021-10-13
    • 2017-06-30
    • 2010-11-07
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多