在shutdown / reboot之前执行命令
我有一台机器运行几个流浪汉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
有什么建议?
如果您的vagrant VM正在使用VirtualBox,您可以修改/ etc / default / virtualbox并更改以下行:
SHUTDOWN_USERS=""
至
SHUTDOWN_USERS="all"
在Ubuntu 14.04上为我修复了它
要在关机或重启时执行脚本:
- 将您的脚本保存在/etc/rc6.d中
- 使其可执行:
sudo chmod +x K99_script
笔记:
- rc6.d中的脚本必须没有.sh扩展名
- 脚本的名称必须以K99开头才能在正确的时间运行。
- 此目录中的脚本按字母顺序执行。
资源
-
使用/etc/init.d/目录中的脚本创建shell可执行文件。
-
由于这必须在关机或重启期间执行,需要在/etc/rc0.d/和/etc/rc6.d中创建软链接。
例:
sudo ln -s /etc/init.d/ /etc/rc0.d/k99stop_vm sudo ln -s /etc/init.d/ /etc/rc6.d/k99stop_vm sudo chmod a+x /etc/init.d/
如何使用Systemd(它更容易)
既然Ubuntu变种和Mint已经转移到systemd,我发现基于上面的旧解决方案不太令人满意。 我在网上搜索了解如何使用systemd进行操作并最终结合其他人的智慧并将其记录为blogspot.com.au上的博客文章,其中包含以下教程。
使用systemd,您可以使用下面的模板创建一个或两个文件来调用脚本,并执行几个命令。 简单。
GUI版本
首先创建要在启动和/或关闭时运行的脚本。 如果你不需要两者,就做一个。 我创建了.scopening_atstart和.scfullcopy_atend。
然后通过右键单击文件,选择属性并确保在权限下选中允许执行文件作为程序,确保它们都是可执行的。
我创建的两个文件填充并保存了ramdisk的内容。 他们还在我的主目录中创建一个文件,以certificate该服务正在运行。 它们的forms如下:
#!/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的编辑器。
使用第一行#!/bin/sh
创建启动和关闭shell脚本,并使用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_stop
和systemctl is-active start_and_stop
可用于监视新服务。
更改关闭的触发条件
上述文件都使用多用户环境的打开或关闭来启动运行脚本。 下面的文件使用四个潜在关闭进程的开头来启动其脚本。 添加或删除Before行+ WantedBy行上的目标将让您更精细地区分:
这个文件是在这篇文章的第二个答案中提出的,但是在我添加一个Install部分之前我无法运行它。
再次,编辑/etc/systemd/service/
的脚本,并使用systemctl enable your_file_name
启用它。 当我更改目标时,我使用了systemclt disable 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
您可以在此处找到解决方案: 在系统关闭/启动时挂起/恢复所有Vagrant框 。
有一个简单的init脚本可以在关闭之前挂起所有正在运行的框。
安装
编辑/etc/init.d/vagrant-boxes
并粘贴上面的文章并保存。 或者从这里下载并保存到/etc/init.d/vagrant-boxes
。 在debian / ubuntu等上运行
# update-rc.d vagrant-boxes defaults 99 01
编号99是序列号,应该大于(在我的情况下,Virtualbox编号为20,这是Debian发行版的默认值)。 第二个数字是关闭计算机时的顺序。 所以,首先做一件事可能会很好。
对于Ubuntu 14.10,你喜欢RC04
而不是RC99
从头开始做什么
- 在
/etc/init.d/scriptName
创建一个脚本 - 通过
ln -s /etc/rc6.d/K04scriptName /etc/init.d/scriptName
链接
我经历的步骤
- 我尝试使用Ubuntu失败- 在启动和关闭时执行脚本
- 我用rc0.d(rc6.d,rc.d)找到了Ubuntu 14.10关机脚本
- 我从/etc/rc6.d/RC99linkName更改为/etc/rc6.d/RC04linkName并且它可以正常工作