सभी वर्चुअलबॉक्स (आवारा) वीएम को शट डाउन कमांड का उपयोग करने के लिए एक आसान में बंद करें (जिसे एक बैश फाइल में डाला जा सकता है)


70

मैं विकास के लिए योनि का उपयोग करता हूं । मैं VMs में से कुछ को बंद करना भूल जाता हूं। जब मैं अपने होस्ट मशीन से लॉग आउट करने जाता हूं, तो उबंटू शटडाउन प्रक्रिया लटकने लगती है।

हो सकता है कि कमांडलाइन-फ़्यू के साथ सभी आवारा पेटियों को बंद करने का कोई तरीका हो? निम्नलिखित की तरह कुछ, लेकिन कुछ है कि, अच्छी तरह से, काम करता है।

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

मुझे योनि का पता नहीं है लेकिन यह VMWare से जुड़ा हुआ है, वर्चुअलबॉक्स नहीं। क्या आप वास्तव में VirtualBox का उपयोग कर रहे हैं?
terdon

@terdon: Vagrant ने शुरुआत में केवल Vbox का समर्थन किया। मुझे लगता है कि अब वे अन्य प्रकार के VM स्वरूपों का समर्थन करते हैं (VMWare को समझें)
सिल्वेन पिनेउ

@SylvainPineau आह, ठीक है। मुझे बस उनके वेबपेज पर एक त्वरित नज़र थी और एक "VMWare एकीकरण" लिंक देखा और ग्रहण किया। स्पष्टीकरण के लिए धन्यवाद।
terdon

1
मैं इस स्क्रिप्ट पर एक नज़र डालूँगा । पूरी ब्लॉग पोस्ट यहाँ है । परीक्षण नहीं किया गया
सिल्वेन पिनेउ

रिचर्ड कृपया अपने प्रश्न का उत्तर संपादित न करें। आप एक अलग उत्तर में अपने प्रश्न का उत्तर देने के लिए स्वतंत्र हैं। मैंने आपको एक अच्छे प्रश्न के लिए उत्थान दिया।
don.joey

जवाबों:


91

वर्चुअल बॉक्स मशीनों के स्क्रिप्ट नियंत्रण के लिए हम VBoxManage कमांड का उपयोग कर सकते हैं :

  • सूची चलने वाली मशीनें (रिटर्न नाम और यूयूआईडी):

    VBoxManage list runningvms
    
  • उन्हें "हाइबरनेटिंग" करके वीएम चलाना बंद करें (डेटा हानि से बचने के लिए पुन: स्थापित)

    VBoxManage controlvm <name|uuid> savestate
    
  • वीएम चलाने वाले पावरऑफ़ (अनुशंसित नहीं है क्योंकि हम अतिथि में डेटा खो सकते हैं)

    VBoxManage controlvm <name|uuid> poweroff
    
  • एसीपीआई-जागरूक अतिथि ओएस में एसीपीआई का उपयोग करें ( poweroffमेहमानों के सुंदर बंद के लिए बेहतर )

    VBoxManage controlvm <name|uuid> acpipowerbutton
    

यह भी देखें: कमांड लाइन का उपयोग करके वर्चुअलबॉक्स में अतिथि ओएस को सुरक्षित रूप से कैसे बंद करें

ओपी से अपडेट

नीचे इस चयनित सही उत्तर के आधार पर, मैंने यह बैश स्क्रिप्ट " $HOME/bin/stop-vagrant.sh" जोड़ दी है । तो अब मेरे पास कुछ ऐसा है जो सुरक्षित रूप से सभी योनि वीएम के एक स्टॉप को शुरू कर सकता है जिसे मैंने सत्र में अभी तक भूल गया हो सकता है।

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

समझाया गया आदेश:

vboxmanage list runningvms | - वर्चुअलबॉक्स के तहत सभी रनिंग वीएमएस की सूची मिलती है

sed -r 's/.*\{(.*)\}/\1/' | - आईडी नंबर के लिए नीचे स्ट्रिंग स्ट्रिप्स

xargs -L1 -I {} VBoxManage controlvm {} savestate - खुले प्रत्येक बॉक्स पर सेव स्टेट कमांड चलाता है।

पर xargs

  • -L1 - एक बार में एक लाइन लें
  • -I {} - अगले आदेश के लिए एक स्थान धारक के रूप में {} का उपयोग करता है

हू हू! उपरोक्त सलाह को देखते हुए, यह कमांड लाइन जादू का काम करती है: vboxmanage list रनवम्स | sed -r 's /.* \ {(। *) \} / \ 1 /' | xargs -L1 -I {} VBoxManage controlvm {} savestate
रिक

1
नोट, -rविकल्प GNU Sed के लिए अद्वितीय है।
जॉर्ज वी। रेली

सर्वश्रेष्ठ जादुई वन-लाइनर मैंने थोड़ी देर में देखा है! बहुत बढ़िया! : D
tftd

1
OSX / macOS पर, आपको -Eइसके बजाय उपयोग करने की आवश्यकता होगी -r। यह विस्तारित नियमित अभिव्यक्तियों का उपयोग करने के लिए ध्वज है।
JayD3e

22

वर्चुअलबॉक्स को हैंडल करने के लिए दूसरा उत्तर बहुत अच्छा है, लेकिन वैग्रंट वर्चुअल मशीनों से निपटने के लिए अपने स्वयं के तंत्र की सुविधा देता है, और जैसा कि टिप्पणियों में से एक में उल्लेख किया गया था, यह फिलहाल वर्चुअलबॉक्स से अधिक का समर्थन करता है, फिलहाल VMWare, लेकिन बाद में कौन जानता है!

यह मेरे लिए काम करने लगता है:

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

ध्यान दें:

यह 1.6 संस्करणों के बाद वैग्रंट संस्करणों के साथ काम करता है, पुराने संस्करणों के लिए, आपको संभवतः अपग्रेड करना चाहिए, लेकिन यदि आप नहीं कर सकते हैं, तो अन्य विकल्पों में से एक जो कि वर्चुअलबॉक्स पर केंद्रित है, बेहतर हो सकता है।


4
यह स्पष्ट रूप से बहुत सही (tm) उत्तर है। @ रिचर्ड को इसके बजाय इसे स्वीकार करने पर विचार करना चाहिए
नाहद

global-statusआदेश दिया गया था Vagrant 1.6 में पेश किया । वैग्रांट के पुराने संस्करणों के उपयोगकर्ता, विशेष रूप से जिन्होंने इसे स्थापित किया है apt-getऔर अभी भी 1.4.3 पर हो सकते हैं, उन्हें इस आदेश का उपयोग करने से पहले अपने वैग्रांट को अपडेट करने की आवश्यकता होगी।
कर्टिस गिब्बी

1
बीएसडी xargsसमर्थन नहीं करता है -r, इसलिए आप इसके gxargsमाध्यम से स्थापित कर सकते हैं brewऔर इसका उपयोग कर सकते हैं ।
kenorb

11

इसके लिए मेरा तंत्र:

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

  • वैश्विक-स्थिति सभी बॉक्सों को सूचीबद्ध करती है
  • फ़िल्टर जो लाइनों के लिए हैं virtualbox(मदद पाठ को फ़िल्टर करता है, यदि आप किसी अन्य प्रदाता का उपयोग कर रहे हैं तो टूट जाएगा)
  • फ़िल्टर जो केवल पहले 9 अक्षर (वैश्विक अद्वितीय आईडी) प्रदर्शित करने के लिए
  • जबकि हम अभी भी उस इनपुट से एक लाइन पढ़ सकते हैं, इसे चर $ लाइन के रूप में पढ़ सकते हैं:
    • उस $ लाइन का प्रिंट आउट लें
    • चलाने vagrant halt $lineकि वैश्विक अद्वितीय ID के लिए आवारा रोकने

यह ऊपर दिए गए वर्चुअलबॉक्स विधि से बेहतर है, क्योंकि यह किसी भी योनि-कॉन्फ़िगर शटडाउन तंत्र को चलाएगा।


3
यह कमांड OS X होस्ट के लिए भी काम करता है। दूसरों OSX और लिनक्स के संस्करणों के बीच से निपटने कमांड लाइन तर्क में अंतर के कारण असफल हो sedऔर awk। धन्यवाद!
एंड्रयू Андрей Листочкин

@ एंड्रयूसेमब्रेटेक्विटेक्लाइरोडीओनस्टाइम कन्फर्म - ओएस एक्स 10 पर अच्छी तरह से काम करता है। हालांकि अन्य ओएस पर परीक्षण नहीं किया गया है।
setevoy

2
उपरोक्त आदेश सभी बक्से को रोकने की कोशिश करता है, चाहे कोई चल रहा हो या नहीं, इस प्रकार निष्पादित होने में लंबा समय लगता है। मेरे लिए, जैसा कि मैं केवल वर्चुअलबॉक्स का उपयोग करता हूं, मैंने केवल "रनिंग" को "वर्चुअलबॉक्स" को "रनिंग" में बदल दिया, केवल रनिंग प्राप्त करने के लिए।
एलेक्स 2 एफपी

यह एक अच्छा जवाब है, लेकिन आप राज्य को बचाने के vagrant suspendबजाय उपयोग करना पसंद कर सकते हैं vagrant haltऔर जल्दी और नीचे के लिए निलंबित कर सकते हैं।
डेविड थॉमस

सच है, और अगर यह आपके लिए काम करता है तो यह बहुत अच्छा है। मुझे वर्चुअलबॉक्स के तहत निलंबित वीएम के साथ बड़े पैमाने पर टाइमकीपिंग की समस्या है, इसलिए मैं इसकी सिफारिश नहीं करूंगा।
एक्वेरियन

5

मामले में अन्य लोगों को यह सवाल आता है: वर्चुअलबॉक्स का उपयोग करने वालों के लिए, यह पहले से ही इस बात का ध्यान रख सकता है, इसमें केवल एक फाइल का संपादन शामिल है:

# 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

कुछ अन्य उत्तरों को मिलाकर, यह सभी रनिंग वर्चुअलबॉक्स आवारा बक्से को बंद कर देगा:

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

यह मेरे लिए काम किया!
डे्रॉन गैलार्डो

3

मैं सिर्फ उपयोग करता हूं vagrant halt। यदि आप इसे बिना किसी तर्क के चलाते हैं, तो यह परिभाषित सभी मशीनों को रोक देता है Vagrantfile


1

यदि आप वैग्रान्ट कमांड को पार्स करने के लिए स्क्रिप्ट लिख रहे हैं, तो यह मशीन-अनुकूल आउटपुट ( --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

देखें: वैग्रांत - मशीन पठनीय आउटपुट


हालाँकि मुझे मानक आउटपुट, जैसे कि पार्स करना आसान लगता है

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

Btw। सैद्धांतिक रूप से vagrantकमांड को इस GH पोस्ट के अनुसार वीएम की सूची के लिए एक नियमित अभिव्यक्ति को स्वीकार करना चाहिए , उदाहरण के लिए:

vagrant suspend '*'

लेकिन यह काम नहीं करता है और एक बग # 7221 है जो इसे ठीक करने के लिए लंबित है।


संबंधित गिटहब टिकट:


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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.