在一个易于使用的bash命令中关闭所有VirtualBox(vagrant)VM(可以放入bash文件)

我使用vagrant进行开发。 我忘了关闭一些虚拟机。 当我退出主机时,Ubuntu关机过程似乎挂起。

可能有一种方法来编写所有流浪盒的关闭与一点命令行fu? 像下面这样的东西,但有些东西是有效的。

for f in $HOME/vagrant; do; cd $f vagrant halt done; 

对于Virtual Box机器的可编写脚本的控件,我们可以使用VBoxManage命令:

  • 列出正在运行的机器(返回名称和UUID):

     VBoxManage list runningvms 
  • 通过“hibernate”它们来停止运行VM(为了避免数据丢失而重新推荐)

     VBoxManage controlvm  savestate 
  • Poweroff运行VM(不推荐,因为我们可能会丢失guest虚拟机中的数据)

     VBoxManage controlvm  poweroff 
  • 在支持ACPI的guest poweroff操作系统中使用ACPI(最好是关闭以便正常关闭guest poweroff

     VBoxManage controlvm  acpipowerbutton 

另请参阅: 如何使用命令行安全地关闭VirtualBox中的Guest OS

从OP更新

根据下面选择的正确答案,我添加了这个bash脚本“ $HOME/bin/stop-vagrant.sh ”。 所以现在我有一些东西可以安全地开始停止我可能在会话中忘记的所有流浪的VM。

 vboxmanage list runningvms | sed -r 's/.*\{(.*)\}/\1/' | xargs -L1 -I {} VBoxManage controlvm {} savestate 

命令解释:

vboxmanage list runningvms | – 获取VirtualBox下所有正在运行的vms的列表

sed -r 's/.*\{(.*)\}/\1/' | – 将字符串剥离到id号

xargs -L1 -I {} VBoxManage controlvm {} savestate – 在每个打开的框上运行save state命令。

xargs

  • -L1 – 一次取一行
  • -I {} – 使用{}作为下一个命令的占位符

另一个答案非常适合处理Virtualbox,但Vagrant有自己的处理虚拟机的机制,正如其中一条评论中所提到的,它支持的不仅仅是VirtualBox,目前仅支持VMWare,但谁知道以后呢!

这似乎对我有用:

 vagrant global-status | awk '/running/{print $1}' | xargs -r -d '\n' -n 1 -- vagrant suspend 

注意:

这适用于1.6之后的Vagrant版本,对于旧版本,你应该升级,但如果你不能,那么关注Virtualbox的其他选项之一可能会更好。

我的机制:

vagrant global-status | grep virtualbox | cut -c 1-9 | while read line; do echo $line; vagrant halt $line; done;

  • global-status列出所有框
  • 筛选包含virtualbox行(筛选出帮助文本,如果您正在使用其他提供程序,则会中断)
  • 过滤即只显示前9个字符(全局唯一ID)
  • 虽然我们仍然可以从该输入中读取一行,但请将其作为变量$ line读取:
    • 打印出$ line
    • run vagrant halt $line为该全局唯一ID暂停vagrant

这比上面的Virtualbox方法更好,因为它也会运行任何流浪汉配置的关闭机制。

如果其他人遇到这个问题:对于那些使用VirtualBox的人来说,它已经可以解决这个问题,只涉及编辑文件:

 # Contents of /etc/default/virtualbox # ... # ... # SHUTDOWN_USERS="foo bar" # check for running VMs of user 'foo' and user 'bar' # 'all' checks for all active users # SHUTDOWN=poweroff # SHUTDOWN=acpibutton # SHUTDOWN=savestate # select one of these shutdown methods for running VMs # acpibutton and savestate causes the init script to wait # 30 seconds for the VMs to shutdown ## My original values # SHUTDOWN_USERS="" # SHUTDOWN=poweroff ## My current values SHUTDOWN_USERS="all" SHUTDOWN=savestate 

好处是没有必要编辑/创建任何logout或init.d stript来运行其他答案中发布的命令。 缺点是这个解决方案特定于VirtualBox。

使用VirtualBox 4.3.18在Ubuntu 14.10上测试。

所有功劳都归功于这篇文章 。

结合其他一些答案,这将关闭所有正在运行的virtualbox vagrant box:

 vagrant global-status | awk '/virtualbox running/{ print $1 }' | xargs vagrant halt 

我只是使用vagrant halt 。 如果在没有进一步参数的情况下运行它,它将停止Vagrantfile定义的所有计算机。

如果您正在编写用于解析Vagrant命令的脚本,则建议解析更加一致的机器友好输出( --machine-readable )。

格式为:

 timestamp,target,type,data... 

所以你可以将它作为CSV文件导入,因为它是以逗号分隔的。

使用shell,它可能更难解析,例如:

 for id in $(vagrant global-status --machine-readable | cut -d, -f5 | grep -B3 running | egrep -o "[0-9a-f]{7}"); do vagrant suspend $id; done 

请参阅: Vagrant – 机器可读输出


但是我发现解析标准输出更容易,例如

 while read id name provider state path; do [ "$state" = "running" ] && vagrant suspend $id; done < <(vagrant global-status) 

顺便说一句。 理论上, vagrant命令应接受根据此GH post暂停的VM列表的正则表达式,例如:

 vagrant suspend '*' 

但它不起作用,并且有一个错误#7221正在等待修复它。


相关GitHub门票:

  • GH#7220:提供额外的选项,用于过滤流浪全球状态列表。
  • GH:#7221:实施--all for suspend或vagrant suspend-all。

这可能适用于您,也可能不适合您;-)适合我

vagrant_halt_all.sh

 #!/usr/bin/env bash if [ -z "$1" ] then OPTS="" else # force close if any arg passed OPTS="-f" fi for i in $(vagrant global-status | grep running | awk '{print $1}'); do DIR=$(vagrant global-status | grep running | awk '{print $5}') cd "$DIR"; OUT=$(vagrant halt); echo "attempted to halt $i: $OUT" done