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


18

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

我已经研究了如何使用cron进行此操作,但是我认为这不是正确的方法,因为cron在上次打开服务器时未考虑在内。我只能设置定期模式,但他们没有考虑这些数据。

我该如何执行?


4
看一下at(一次性执行)。
dirkt

14
我尚未执行此操作,但是您的登录脚本可以启动,sudo shutdown -h +60这将启动一个60分钟的倒计时计数器以进行关机(暂停)过程。如果您想取消它,可以sudo shutdown -c (尽管不使用cron)
guiverc

7
根据您任务的性质,可能值得在docker容器中运行它们,因此您不必担心关闭服务器。容器被创建,它运行您的任务,然后销毁。
维森特·奥利维特·里耶拉

6
不要期望由此带来任何真正的安全利益。大多数漏洞可以在不到一秒钟的时间内被利用,因此一小时后关闭电源并不能阻止利用。发现漏洞的攻击者可以等待您打开计算机电源以进行攻击。
卡巴斯德(Kasperd),

2
回复:@kasperd的评论,我将其改写为说,无论实际上在线多少,您都需要服务器上完全相同的安全性。请注意,这是一台服务器,因此它连接到某物,这意味着某物会在打开时知道;自动扫描不是您所担心的,它是任何类型的连接,您无法避免,因此始终具有最大的安全性唯一的办法。
StephenG

Answers:


23

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

echo "sudo shutdown -P +60" >> ~/.profile

11
时间以分钟为单位,而不是秒。尝试shutdown -k -P 3600vs shutdown -k -P 60-k打印墙消息,但没有其他效果)
sebasth

12
但是先尝试一次命令,您不希望将即时关机绑定到您的配置文件!
FabianRöling,

17
我想每个ssh登录都会引起新的关闭请求。计数器会重置吗?
JoL

4
值得一提的是,如关机手册中所述,最近5分钟内将不允许登录。
JoL

6
请注意,登录后60分钟与引导后60分钟不同。如果您启动计算机然后忘记登录怎么办?
哈根·冯·埃岑

69

有几种选择。

  • 直接向shutdown -P以下人员提供时间:

    shutdown -P +60
    

    请注意,shutdown 手册页还指出:

    如果使用time参数,则在系统关闭前5分钟创建/ run / nologin文件,以确保不允许进一步的登录。

  • 使用at命令。

  • 创建一个在启动时运行的systemd单元文件初始化脚本shutdown -P 60

  • @reboot引导后使用cron's 运行命令。

    添加到(根)crontab:

    @reboot shutdown -P +60
    

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


2
我认为,使用该sleep命令,您仍然需要指定一个时间shutdown- now如果我们已经完成等待,我们希望将其用于该参数(但是请注意,在此之前您不会收到太多警告来保存您的工作从你下方消失!)。
Toby Speight '18

1
尽管shutdown -P 60有效,但不是调用命令的方式。根据手册页应该使用shutdown -P +60。---同样,不带时间参数的关机(在示例中sleep 3600 && shutdown -P)将延迟一分钟(如shutdown -P +1)。正如Toby Speight所写,您可能想要使用shutdown -P now
pabouk

33

这看起来像XY问题

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

如果您在60分钟后关闭,则可能会遇到一个特别复杂的问题,那就是需要更多时间。许多以前的解决方案都很难使关闭延迟变得容易。

如果该任务不是交互式任务,而是由另一台计算机自动触发的脚本任务,则@sdkks为此提供了一个很好的解决方案;您真的应该只命令脚本及其所有任务完成后立即关闭计算机电源。

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

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

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

如果您想变得更加积极一些并断开空闲的终端会话,则可以将先前的方法与自动断开空闲的SSH会话 ClientAliveInterval和结合起来ClientAliveCountMax。如果没有SSH,但是有本地终端会话,则另一种方法是使用命令返回的终端空闲时间w


2
这是非常重要的一点。无论采用哪种实施方式-确保您也可以取消关闭符合您的利益。
影子

1
如果它仍在60m处运行,则出了点问题,因此也许可以重新开始。这可能是非常昂贵的云计算。一次没有确保关闭就让我退了4000多美元。
mckenzm

8

尽管此处的先前答案都满足完善的要求,但是您也可以在完成任务后立即关闭机器电源。

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

您将能够:

  1. trapEXIT您的自动化shell脚本设置一个,这意味着您终止了自动化任务
  2. trap为您的设置a .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

这可以在.bashrc选项#2 的结尾处,也可以在脚本中选项#1的顶部某处。

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

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

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

我有一个简单的bash模板,可以使脚本更易于调试。也许可能有用。请看这个要点


同意,并确保一天中有一段时间从cron关闭。这是死人的刹车。
mckenzm

@Abigail用于脚本,它必须在上面,因为.bashrc如果有其他内容覆盖它,我希望使用底部。您的顾虑似乎还不清楚,您能否在repl.it上分享一个示例片段?
sdkks

@mckenzm我不明白。您可以分享示例代码或更多说明吗?
sdkks 18-10-5,0

5

在阐述@dirkt评论,你可以插入一个at在命令你.bashrc.profile或任何文件上登录你的shell用来登录60分钟后安排自动关机。

就像是:

at now + 60 minutes -f /sbin/halt

这个任务就在at胡同里。您还可以at/var/spool/
sdkks

5
我建议不要at在这种情况下使用,因为它在重新启动后仍然有效。如果OP要登录,手动关闭然后在一个小时的时间内再次登录,那么他将在上一次登录第一次计划的关闭程序后的一个小时之前开始运行。
亚伦

@Aaron是的。还没想到。引导持久性是此解决方案的警告。
sdkks

5

下面的命令command使用参数运行,并且如果成功完成,则假定用户可以运行,它将立即关闭该框poweroff。它可能需要使用sudo poweroff

command --parameters && poweroff

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

command --parameters ; poweroff

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

command --parameters ; sleep 3600 ; poweroff

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

timeout 1h command --parameters ; poweroff

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


3

如果您真的担心安全性,请在电源上使用机械插座计时器。只需将其设置为您希望其关闭的任何时间即可。这样,没有人可以远程登录并禁用关机。您将需要物理访问。


2
文件系统损坏?
Xen2050

@ Xen2050在任何现代(日记)文件系统上都不是问题。
汤姆(Tom)

1
@Tom如果有日志记录,您是否有强制umount的源将永远不会导致文件系统损坏?对我来说听起来很新,我想继续阅读。至少它必须将文件系统标记为脏文件,强制使用fsck对吗?
Xen2050

1
在大多数情况下,它只应重播日志并进行处理。断电不应导致日记文件系统上的文件系统损坏,尽管不能保证,除非您使用专门为这种情况设计的文件系统(例如ZFS)。
汤姆(Tom)

1
日志重播可能会失败-几周前,在没有UPS的机器断电½秒后,我遇到了非常困难的fsck会话。那是在日志中使用ext4;这不是完全无敌的!
Toby Speight

2

如果您在systemd机器上,可以使用单调计时器

计时器单元 /etc/systemd/system/shutdown_after_an_hour.timer

[Unit]
Description=shutdown after an hour

[Timer]
OnBootSec=1h

[Install]
WantedBy=timers.target

计时器单位/etc/systemd/system/shutdown_after_an_hour.service

[Unit]
Description=shutdown after an hour

[Service]
ExecStart=/sbin/poweroff --force --no-wall
Type=oneshot

通过以下方式启用

# systemctl enable shutdown_after_an_hour.timer

可通过以下方式获取其状态(尤其是关机前还剩下多少时间)

# systemctl list-timers shutdown_after_an_hour.timer

它将在下次重新启动时起作用,在systemctl start创建会话期间对它没有用,因为它将不起作用(因为它不是在重新引导期间触发的),或者如果超过一小时就立即关闭计算机。实际上,我不知道会发生哪种情况,我从未测试过这种具体情况。


1

尝试将脚本(sudo shutdown -P 3600)放在/etc/init.d目录中以在启动时自动运行它。

或尝试使用anacron,在/etc/anacrontab文件中添加命令。我还建议nohup在命令前使用该命令,以确保注销后该命令仍然有效。


1
根据发行版的不同,它可能无法仅通过init.d来执行
sdkks

@sdkks,您是对的。也可以考虑Anacron。将脚本放在/ etc / anacrontab中,该脚本在注销时也与'nohup'一起使用。
Saveriofr '18 -10-2

1
@Saveriofr您可以编辑答案以提高其质量(比发布其他信息作为注释更好)。
Anthony G-Monica的正义'18

1

利用Shell的注销文件

如果仅需要服务器执行由UID启动的交互式或非交互式任务,请考虑将关机命令放入〜/ .bash_logout文件中。在GNU Bash的手册说:

当交互式登录Shell退出或非交互式登录Shell执行exit内置命令时,Bash会从〜/ .bash_logout文件(如果存在)中读取并执行命令。

因此,加入“须藤关机”或类似的注销文件将关闭服务器电源为您注销,一旦当前会话,或者在非交互的Bash会议呼叫exit。你也可以选择使用或延时传递到关机如果您希望推迟关机。

对于更具交互性的方法,可以将以下Bashisms放入注销文件:

# Shutdown unless N or n is pressed within 30 seconds.
shopt -s nocasematch
read -t 30 -N 1 -p 'Shutdown now? (Y/n) '
[[ "$REPLY" =~ n ]] || sudo poweroff

注意事项

关于此解决方案,需要注意一些注意事项:

  • 即使在由X Windows启动的终端下,这也可能会起作用,但对于不是由X startx类似的启动的X11会话,则可能不起作用。
  • 如果您有调用的非交互式脚本,则exit可能会遇到意外关闭的情况。
  • 如果未NOPASSWD为shutdown命令指定密码,或者sudo -v在运行shutdown命令之前尚未调用密码,则sudoers文件可能会提示您输入密码。
  • 我可能还没有想到其他边缘情况。

简而言之,您可能需要考虑这种方法是否满足您的实际需求,或者完全不同的方法(例如监视是否缺少登录用户或其他替代方法)是否是更好的选择。您的里程肯定会有所不同。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.