关闭/重新启动之前执行命令


18

我有一台机器正在运行几个无所事事的VM。我的问题是,有时我忘记关闭那些VM,然后再关闭或重新引导计算机。因此,我的机器陷入了此消息:waiting for vboxnet0 to become free

我搜索了解决方案,然后找到此页面:

http://en.kioskea.net/faq/3348-ubuntu-executing-a-script-at-startup-and-shutdown

我尝试使用它们进行关机,但不起作用。

我为该命令编写了一个sh文件:

#!/bin/bash

cd ~/workspace/git/mediaservice
vagrant halt

有什么建议么?


4
链接中的方法有效,并且适用于所有Linux版本,因此您的脚本是错误的;)关机时不认识该用户,因为它是由root用户完成的。因此,删除“〜”并使其成为完整路径。
Rinzwind

它行得通吗?我遵循了类似gist.github.com/ymc-geha/8416723的手册,但是在ubuntu 14.04上没有为我工作
user2135804 2014年

@ user2135804我认为可以。.但是实际上它对Vagrant无效。.我尝试了其他方法,效果很好。
SERPRO 2014年

1
顺便说一下,您要描述的错误在这里
加勒特2015年

1
如错误报告所示,此问题已修复,将包含在VirtualBox 4.3.29中。
加勒特2015年

Answers:


11

如果您的无用虚拟机使用的是VirtualBox,则可以修改/ etc / default / virtualbox并更改以下内容:

SHUTDOWN_USERS=""

SHUTDOWN_USERS="all"

这为我在Ubuntu 14.04上修复了它


1
实际上,与此连接的虚拟盒子中有一张开放票。virtualbox.org/ticket/12264。我建议使用SHUTDOWN_USERS=`cut -d: -f1 /etc/passwd`而不是SHUTDOWN_USERS="all"
running.t

我也在使用VirtualBox的Vagrant使用Ubuntu 14.04,但我没有任何/etc/default/virtualbox文件...
Garrett 2015年

21

要在关闭或重新启动时执行脚本:

  1. 将脚本保存在/etc/rc6.d中
  2. 使它可执行: sudo chmod +x K99_script

笔记:

  • rc6.d中的脚本必须没有.sh扩展名
  • 您的脚本名称必须以K99开头才能在正确的时间运行。
  • 该目录中的脚本按字母顺序执行。

资源


1
确实。正确命名它以使其在正确的时间运行非常重要。
shivams,2015年

1
我在/etc/rc6.d中放了一个脚本,它没有在关机时运行。我把它放在/etc/rc0.d中,它确实在关机时运行。rc.6可能仅用于重新启动。
Erel Segal-Halevi,2015年

2
@Erel Segal-Halevi我刚刚尝试将K99脚本添加到/etc/rc6.d中,但未执行。在其他脚本中,有一行** bold K10reboot-> ../init.d/reboot ** code,因此看来K99脚本将永远不会执行!
David Walker

下面的Ravi答案是一个更好的选择,因为它使用符号链接来确保脚本在关闭和重新启动时都运行。我也认为大多数系统文件都倾向于使用此方法。
艾迪(Eddie)

12

如何使用Systemd做到这一点(更容易)

现在,Ubuntu变体和Mint已迁移到systemd,我发现基于上述内容的旧解决方案不太令人满意。我在网上搜索了有关如何使用systemd进行搜索的信息,最后结合了其他人的智慧并将其记录为blogspot.com.au上的博客文章,其中包含以下教程。

使用systemd,您可以创建一个或两个文件,以使用以下模板调用脚本,并执行几个命令。简单。


GUI版本

首先创建要在启动和/或关闭时运行的脚本。如果您不需要两者,请只做一个。我创建了.scopening_atstart和.scfullcopy_atend。

然后,通过右键单击文件,选择属性并确保在权限下选中了“允许将文件作为程序执行”,以确保它们都可执行。

在此处输入图片说明

我创建的两个文件填充并保存了虚拟磁盘的内容。他们还在我的主目录中创建一个文件,以证明该服务正在运行。它们的形式为:

#!/bin/sh
cp -pru /home/john/zRamdisk/subdirectory1/* /home/john/.wine/drive_c/subdirectory1/
rm /home/john/stop_time
date +%D' '%T > /home/john/stop_time

然后,我以root用户身份打开文件管理器,打开/etc/systemd/system并创建了文件startup.service和文件save-ramdisk.service。显然,您可以选择自己的名称,通用名称可能包含一个名为johns_start.service的启动文件和一个名为johns_shutdown.service的关机文件。只是不要选择现有的服务名称。

[Unit]
Description=Startup Applications

[Service]
Type=oneshot
RemainAfterExit=false
ExecStart=/home/john/.scopening_atstart

[Install]
WantedBy=multi-user.target

[Unit]
Description=Save Ramdisk to Wine drive C

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/john/.scfullcopy_atend

[Install]
WantedBy=multi-user.target

您可以使用相同的服务文件,用可执行脚本的完整路径替换我的。

最后,对于每个命令,执行命令systemctl enable your_files_name(但不带后缀服务)。所以我的第一个是systemctl enable startup

重新启动计算机一次以启动服务。每当systemd进入多用户目标时,将执行启动服务,而当退出多用户目标时,将执行停止服务。下面将介绍具有不同激活条件的替代服务文件。

其他有用的命令包括:

systemctl已启用启动
systemctl是活动启动
systemctl重新启动启动

可以在上面的参考资料中找到更多信息。



CLI(命令行)版本

该描述假定您是从主目录而不是/ home / john进行操作,并根据需要使用sudo,并选择在我编写vim或svim的编辑器。

在第一行创建启动和关闭Shell脚本,#!/bin/sh并使用使其可执行chmod +x my_new_filename

如上创建两个文件,或者在此示例中,创建一个文件来处理启动和关闭任务。我将在我的主目录中执行脚本,但是@don_crissti在Stack Exchange上显示了一些替代方法。

svim /etc/systemd/system/start_and_stop.service

并复制文件内容:

[Unit]
Description=Run Scripts at Start and Stop

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/home/john/.startup_commands  #your paths and filenames
ExecStop=/home/john/.shutdown_commands

[Install]
WantedBy=multi-user.target

然后使用以下命令启用服务

systemctl enable start_and_stop

并重新启动系统,然后服务将被激活。这些命令systemctl is-enabled start_and_stopsystemctl is-active start_and_stop可用于监视新服务。



更改关机的触发条件

首先,这些文件使用多用户环境的打开或关闭来启动运行脚本。下面的文件使用四个可能的关闭过程的开始来启动其脚本。在Before行+ WantedBy行上添加或删除目标,可以使您更好地区分:

此文件是在本文的第二个答案提出的,但是直到添加了“安装”部分,我才能使其运行。

再次,在中编辑脚本/etc/systemd/service/并使用启用它systemctl enable your_file_name。更改目标时,我使用了该systemclt disable file_name命令,然后重新启用了该命令,将其符号链接到目标目录。重新启动,该服务将运行。

[Unit]
Description=Do something required
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
# This works because it is installed in the target and will be
#   executed before the target state is entered
# Also consider kexec.target

[Service]
Type=oneshot
ExecStart=/home/john/.my_script  #your path and filename

[Install]
WantedBy=halt.target reboot.target shutdown.target

7
更轻松?比什么还容易?比攀登珠穆朗玛峰更容易?在这里发布的所有其他解决方案都比这更容易...
Fran Marzoa

哇,这是一个完整而体面的答案,每个人都应该做的-/etc/rc6.d的命名问题和混乱表明这些都不是很好的答案。如果一个过程很简单,那么它不一定有能力安全地结束它。请参阅[安装]部分-您可以确定您的脚本将在正确的时间执行。此外,因为答案很长,并不意味着答案复杂!谢谢顺便说一句,John9631,这个答案很完美,对于在任务关键时刻创建安全高效的脚本非常有用……
米勒大猩猩

11
  1. 在/etc/init.d/目录中使用脚本创建Shell可执行文件。

  2. 由于必须在关机或重新引导期间执行此操作,因此需要在/etc/rc0.d/和/etc/rc6.d中创建软链接

例:

sudo ln -s /etc/init.d/<your_file> /etc/rc0.d/k99stop_vm
sudo ln -s /etc/init.d/<your_file> /etc/rc6.d/k99stop_vm
sudo chmod a+x /etc/init.d/<your_file>

chmod更改链接目标的许可标志,这对于两个参数都是相同的。同时指定它们都是多余的。
David Foerster,2014年

2

您可以在此处找到解决方案:在系统关闭/启动时挂起/恢复所有Vagrant框

有一个简单的初始化脚本,可以在关闭之前挂起所有正在运行的盒子。

安装

编辑/etc/init.d/vagrant-boxes并粘贴以上文章中的脚本并保存。或从此处下载并将其保存到/etc/init.d/vagrant-boxes。在debian / ubuntu等上,运行

# update-rc.d vagrant-boxes defaults 99 01

数字99是序列号,并且应大于(在我的情况下为Virtualbox数字20,顺便说一下,这是Debian发行版中的默认值)。第二个数字是关闭计算机时的顺序。因此,首先做可能会很好。


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.