1つの使いやすいbashコマンド(bashファイルに入れることができる)ですべてのVirtualBox(迷走)VMをシャットダウンする


70

開発にvagrantを使用します。いくつかのVMをシャットダウンするのを忘れています。ホストマシンからログアウトすると、Ubuntuのシャットダウンプロセスがハングしたように見えます。

ちょっとしたコマンドラインですべての浮浪者ボックスのスクリプトを作成する方法がありますか?次のようなものですが、うまくいくものです。

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

浮浪者は知りませんが、VirtualBoxではなくVMWareにリンクされているようです。VirtualBoxを実際に使用していますか?
テルドン

@terdon:Vagrantは最初はVboxのみをサポートしていました。私は、彼らが今、VMフォーマット(VMWareのを理解して)他のタイプのサポートを考える
シルヴァン・ピノー

@SylvainPineauああ、OK。私は彼らのウェブページをざっと見て、「VMWare統合」リンクを見ただけで想定しました。説明をありがとう。
テルドン

1
このスクリプトを見てみましょう。完全なブログ投稿はこちらです。未テスト
シルヴァンピノー14

リチャードは質問の答えを編集しないでください。独自の質問に別の回答で自由に回答できます。良い質問に賛成票を投じました。
don.joey

回答:


91

Virtual Boxマシンをスクリプトで制御するには、VBoxManageコマンドを使用できます。

  • 実行中のマシンのリスト(名前とUUIDを返します):

    VBoxManage list runningvms
    
  • VMを「休止」して実行を停止します(データの損失を防ぐために推奨)

    VBoxManage controlvm <name|uuid> savestate
    
  • VMのパワーオフ(ゲストのデータを失う可能性があるため推奨されません)

    VBoxManage controlvm <name|uuid> poweroff
    
  • ACPI対応のゲストOSでACPIを使用します(ゲストのpoweroff正常なシャットダウンに適しています)

    VBoxManage controlvm <name|uuid> acpipowerbutton
    

参照:コマンドラインを使用してVirtualBoxでゲスト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 -開いている各ボックスで状態保存コマンドを実行します。

オン xargs

  • -L1 -一度に1行取る
  • -I {} -次のコマンドのプレースホルダーとして{}を使用します

フーフー!上記のアドバイスを考えると、このコマンドラインは魔法のように動作します:vboxmanage list runningvms | sed -r 's /.* \ {(。*)\} / \ 1 /' | xargs -L1 -I {} VBoxManage controlvm {} savestate
リック

1
この-rオプションはGNU Sedに固有のものであることに注意してください。
ジョージV.ライリー

しばらく見てきた最高の魔法のワンライナー!よくやった!:D
tftd

1
OSX / macOSでは、の-E代わりに使用する必要があります-r。これは、拡張正規表現を使用するためのフラグです。
JayD3e

22

もう1つの答えはVirtualboxの処理に最適ですが、VagrantはVirtual Machinesを処理する独自のメカニズムを備えており、コメントの1つで述べたように、VirtualBoxだけでなく、現時点では単なるVMWareをサポートしていますが、後で知っています!

これは私のために働くようです:

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

注意:

これは1.6以降のVagrantバージョンで機能します。古いバージョンの場合は、おそらくアップグレードする必要がありますが、アップグレードできない場合は、Virtualboxに焦点を当てた他のオプションのいずれかが優れている可能性があります。


4
これは明らかにはるかに正しい(tm)答えです。@Richardではなく、これを受け入れることを検討すべきである
nhed

このglobal-statusコマンドはVagrant 1.6で導入されました。Vagrantの古いバージョンのユーザー、特にapt-get1.4.3を使用してインストールしたユーザーは、このコマンドを使用する前にVagrantインストールを更新する必要があります。
カーティスギビー

1
BSD xargsはをサポートしていないため-rgxargs経由brewでインストールして代わりに使用できます。
ケノーブ

11

これの私のメカニズム:

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を印刷する
    • vagrant halt $lineそのグローバルな一意のIDの浮浪者を停止して実行する

これは、vagrantで構成されたシャットダウンメカニズムも実行するため、上記のVirtualboxメソッドよりも優れています。


3
このコマンドはOS Xホストでも機能します。その他は、OSXとLinuxバージョンのsedとのコマンドライン引数の処理の違いにより失敗しawkます。ありがとう!
アンドリューАндрейЛисточкин16年

@AndrewАндрейЛисточкин確認-OS X 10で正常に動作します。ただし、他のOSではテストされません。
setevoy

2
上記のコマンドは、実行中かどうかに関係なく、すべてのボックスを停止しようとするため、実行に時間がかかります。私にとっては、virtualboxのみを使用しているため、「virtualbox」grepを「running」に変更して、実行中のものだけを取得しました。
Alex2php

これは良い答えですが、状態を保存し、より速く上下するためにサスペンドするvagrant suspend代わりに使用することができますvagrant halt
デビッドトーマス

確かに、それがあなたのために働くなら、それは素晴らしいことです。Virtualboxの下でサスペンドされたVMで大規模な計時の問題が発生したため、お勧めしません。
アクエリオン

5

他の人がこの質問に答える場合: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

init.d利点は、他の回答に投稿されたコマンドを実行するためにログアウトまたはストリプトを編集/作成する必要がないことです。欠点は、このソリューションがVirtualBoxに固有であるということです。

VirtualBox 4.3.18を使用したUbuntu 14.10でテスト済み。

すべてのクレジットはこの投稿にあります。


5

他のいくつかの回答を組み合わせて、実行中のすべてのvirtualbox vagrantボックスを閉じます:

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

これは私のために働いた!
デイロンガヤルド

3

使用するだけvagrant haltです。さらに引数を指定せずに実行すると、で定義されているすべてのマシンが停止しますVagrantfile


1

Vagrantコマンドを解析するスクリプトを作成している場合--machine-readableは、より一貫性のあるマシンフレンドリーな出力()を解析することをお勧めします。

形式は次のとおりです。

timestamp,target,type,data...

カンマ区切りであるため、CSVファイルとしてインポートできます。

シェルを使用すると、たとえば次のように解析するのが難しくなります。

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 投稿に従って一時停止するVMのリストの正規表現を受け入れる必要があります。次に例を示します。

vagrant suspend '*'

しかし、それは機能せず、それを修正するために保留中のバグ#7221があります。


関連するGitHubチケット:


0

これはあなたのために働くかもしれないし、そうでないかもしれない;-)私のために働く

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.