Tüm VirtualBox (vagrant) VM'lerini bash komutunu kullanmak için bir bash komutunda kapatma (bir bash dosyasına yerleştirilebilir)


70

Gelişim için serseriyi kullanıyorum . Birkaç sanal makineyi kapatmayı unuttum. Ana makinemden çıkış yaptığımda, Ubuntu kapanma işlemi kilitleniyor gibi görünüyor.

Tüm aşağılayıcı kutulara bir miktar komut satırı-fu ile yakın bir yazı yazmanın bir yolu olabilir mi? Aşağıdaki gibi bir şey, ama iyi çalışan bir şey.

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

Serseriyi tanımıyorum, ancak VirtualBox ile değil VMWare ile bağlantılı görünüyor. Aslında VirtualBox kullanıyor musunuz?
terdon

@terdon: Vagrant başlangıçta sadece Vbox'ı destekledi. Sanırım şimdi diğer VM formatlarını destekliyorlar (
VMWare'i

@SylvainPineau ah, tamam. Web sayfalarına hızlıca baktım ve bir "VMWare entegrasyonu" bağlantısı gördüm ve kabul ettim. Açıklama için teşekkürler.
terdon

1
Bu senaryoya bir göz atardım . Tam blog yazısı burada . Test edilmedi
Sylvain Pineau

Richard, lütfen sorunuzdaki cevabı düzenlemeyin. Kendi sorunuza ayrı bir cevapta cevap vermekte özgürsünüz. Sana iyi bir soru için bir oy verdim.
don.joey

Yanıtlar:


91

Sanal Kutu makinelerinin komut dosyası denetimi için VBoxManage komutlarını kullanabiliriz:

  • Çalışan makineleri listeleyin (adı ve UUID değerini döndürür):

    VBoxManage list runningvms
    
  • VM'leri çalıştırmayı "hazırda bekletme" yaparak durdurun (veri kaybını önlemek için yeniden düzenlendi)

    VBoxManage controlvm <name|uuid> savestate
    
  • Poweroff çalışan VM'ler (konukdaki verileri kaybedebileceğimiz için önerilmez)

    VBoxManage controlvm <name|uuid> poweroff
    
  • ACPI'yi tanıyan bir misafir işletim sisteminde ACPI kullanın poweroff(misafirlerin zarif bir şekilde kapatılması tercih edilir )

    VBoxManage controlvm <name|uuid> acpipowerbutton
    

Ayrıca bkz: Konuk OS'de VirtualBox'da komut satırını kullanarak güvenli bir şekilde kapatma

OP’den güncelleme

Aşağıdaki bu doğru cevaba dayanarak, bu bash betiğini " $HOME/bin/stop-vagrant.sh" ekledim . Şimdi, oturumumda henüz unutmuş olabileceğim tüm serser VM'leri güvenli bir şekilde durdurabilecek bir şeye sahibim.

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

Açıklanan Komut:

vboxmanage list runningvms | - VirtualBox altında çalışan tüm vms'lerin bir listesini alır

sed -r 's/.*\{(.*)\}/\1/' | - dizgiyi id numarasına indirir

xargs -L1 -I {} VBoxManage controlvm {} savestate - Açık olan her kutuya kaydetme durumu komutunu çalıştırır.

üzerinde xargs

  • -L1 - bir seferde bir satır almak
  • -I {} - {} bir sonraki komut için yer tutucu olarak

Hoo Hoo! Yukarıdaki tavsiyeler göz önüne alındığında, bu komut satırı sihirle çalışır: vboxmanage list runningvms | sed -r 's /.* \ {(. *) \} / \ 1 /' | xargs -L1 -I {} VBoxManage controlvm {} savestate
Rick

1
Not, -rseçenek GNU Sed'e özgüdür.
George V. Reilly

Bir süredir gördüğüm en iyi büyülü tek astar! Aferin! : D
tftd

1
OSX / macOS'ta, -Eyerine kullanmanız gerekir -r. Genişletilmiş düzenli ifadeleri kullanmanın bayrağı.
JayD3e,

22

Diğer cevap, Virtualbox ile başa çıkmak için harikadır, ancak Vagrant, Virtual Machines ile başa çıkmak için kendi mekanizmalarına sahiptir ve yorumlardan birinde belirtildiği gibi, şu anda sadece VMWare'den sadece VirtualBox'tan daha fazlasını destekler, fakat sonradan kim bilir!

Bu benim için çalışıyor gibi görünüyor:

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

Not:

Bu 1.6'dan sonra Vagrant sürümleriyle çalışır, eski sürümler için muhtemelen yükseltmelisiniz, ancak yapamazsanız, Virtualbox'a odaklanan seçeneklerden biri daha iyi olabilir.


4
Bu açıkçası çok daha doğru bir cevap (tm). @Richard bunun yerine kabul etmeyi düşünmelidir
17'de

global-statusKomut edildi Vagrant 1.6 tanıtıldı . Vagrant'ın eski sürümlerindeki, özellikle onu yükleyen apt-getve hala 1.4.3'teki kullanıcıların, bu komutu kullanmadan önce Vagrant yüklemelerini güncellemeleri gerekir.
Curtis Gibby

1
BSD xargsdesteklemez -r, bu nedenle kurabilir gxargsyoluyla brewve bunun yerine kullanın.
kenorb

11

Bunun için mekanizmam:

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

  • global-statü tüm kutuları listeler
  • içeren satırlar için filtre uygulayın virtualbox(Yardım metnini filtreler, başka bir sağlayıcı kullanıyorsanız bozulur)
  • Sadece ilk 9 karakteri gösterecek şekilde filtrele
  • Bu girişten hala bir satır okuyabilsek de, $ line değişkeni olarak okuyun:
    • Bu $ hattını yazdır
    • çalıştırmak vagrant halt $lineküresel benzersiz bir kimlik için serseri durdurma

Bu, yukarıdaki Virtualbox yönteminden daha iyidir, çünkü herhangi bir serseri yapılandırılmış kapatma mekanizmasını da çalıştıracaktır.


3
Bu komut OS X ana bilgisayarları için de geçerlidir. Diğerleri nedeniyle OSX ve Linux sürümleri arasında taşıma komut satırı argümanları farklılıklardan başarısız sedve awk. Teşekkürler!
Andrew Андрей Листочкин

@ AndrewАндрейЛисточкин Onayla - OS X 10'da çalışır. Diğer işletim sistemlerinde test edilmedi.
setevoy

2
Yukarıdaki komut, çalışıp çalışmadığına bakılmaksızın tüm kutuları durdurmaya çalışır, bu nedenle yürütülmesi uzun zaman alır. Benim için sadece sanal kutusu kullandığım için, sadece çalışanları elde etmek için "sanal kutusu" grep'i "çalışıyor" olarak değiştirdim.
Alex2php

Bu iyi bir cevap, ancak devleti kurtarmak ve daha hızlı bir şekilde durup durmak için kullanmak vagrant suspendyerine kullanmak isteyebilirsiniz vagrant halt.
David Thomas,

Doğru, ve senin için işe yararsa, bu harika. Virtualbox altında askıya alınmış sanal makinelerde büyük zaman işleyişi sorunları yaşadım, bu yüzden bunu tavsiye etmem.
Aquarion

5

Başkalarının bu soruyu alması durumunda: VirtualBox kullananlar için, bununla zaten ilgilenebilir, sadece bir dosyayı düzenlemeyi içerir:

# 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.dDiğer taraf, diğer cevaplarda gönderilen komutları çalıştırmak için herhangi bir oturumu kapatmak veya çıkarmak için gerekli değildir . Olumsuz tarafı bu çözüm VirtualBox'a özgüdür.

VirtualBox 4.3.18 ile Ubuntu 14.10'da test edilmiştir.

Tüm kredi bu yazıya gider .


5

Diğer cevapların bazılarını birleştirdiğinizde, bu, çalışan tüm sanal kutu serseri kutularını kapatır:

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

Bu benim için çalıştı!
Dayron Gallardo

3

Ben sadece kullanıyorum vagrant halt. Başka bir argüman olmadan çalıştırırsanız, içinde tanımlanan tüm makineleri durdurur Vagrantfile.


1

Vagrant komutlarını ayrıştırmak için komut dosyaları yazıyorsanız --machine-readable, daha tutarlı olan makine dostu çıktıyı ( ) ayrıştırmanız önerilir .

Format:

timestamp,target,type,data...

böylece virgülle ayrıldığından CSV dosyası olarak içe aktarabilirsiniz.

Kabuk ile, örneğin ayrıştırmak daha zor olabilir, örneğin:

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

Bakınız: Vagrant - Makine tarafından okunabilir çıkış


Ancak standart çıktının ayrıştırılmasını daha kolay buluyorum, örneğin

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

Btw. Teorik olarak vagrantbu GH uyarınca askıya VM'lerin listesi için normal bir ifade kabul etmelidir komutu sonrası , örneğin:

vagrant suspend '*'

fakat işe yaramıyor ve düzeltmek için bekleyen bir # 7221 hatası var.


İlgili GitHub biletleri:


0

Bu sizin için çalışmayabilir veya çalışmayabilir ;-) Benim için çalışıyor

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.