2011-08-15 12 views
15

Chcę przechodzić przez uruchomione maszyny wirtualne i zwracać tylko wartości między ofertami.Uzyskaj listę działających maszyn wirtualnych za pomocą programu VBoxManage

Więc to polecenie:

VBoxManage list runningvms 

powraca:

"UbuntuServer" {7ef01f8d-a7d5-4405-af42-94d85f999dff} 

A ja tylko chcę, żeby powrócić:

UbuntuServer 

To, co mam tak daleko (nie):

#!/bin/bash 
for machine in `cat VBoxManage list runningvms`; do 
     echo "$machine" 
done 
exit 

Odpowiedz

16

Ostrzeżenie: wszystko to jest ryzykowne, jeśli Twoje nazwy maszyn wirtualnych zawierają znaki globu powłoki lub zawierają spacje.


można zrobić coś takiego, jeśli istnieje tylko jeden uruchomiony VM:

read machine stuff <<< $(VBoxManage list runningvms) 
echo "$machine" 

alternatywna z tablicami bash (te same warunki):

vbm=($(VBoxManage list runningvms)) 
echo "${vbm[0]}" 

Jeśli program zwróci więcej niż jedna linia, bardziej klasyczne podejście to:

for machine in $(VBoxManage list runningvms|cut -d" " -f 1); do 
    echo "$machine" 
done 
+0

"Klasyczne podejście" to zła praktyka, podobnie jak podejście 'array = ($ (...)); oba na przykład zastąpią pojedynczy token '*' w twoim pliku wejściowym listą plików w bieżącym katalogu. Zobacz [Nie czytaj linii z tekstem] (http://mywiki.wooledge.org/DontReadLinesWithFor), [BashPitfalls # 50] (http://mywiki.wooledge.org/BashPitfalls#hosts.3D.28_.24.28aws_ ... 29_.29) i [BashFAQ # 1] (http://mywiki.wooledge.org/BashFAQ/001) –

+0

Potrzebujesz podziału na słowa dla tego konkretnego przykładu, a nazwa maszyny wirtualnej pasująca do wzorca globu wydaje się mało prawdopodobna. – Mat

+0

Najgorsze zdarzenie utraty danych, w którym się pojawiłem, miało miejsce, ponieważ ktoś zignorował zdarzenie "niemożliwe" (program tworzący pliki "nigdy nie mógł" stworzyć niczego nie pasującego [0-9a-f] {24}; błąd w bibliotece innej firmy uszkodził wskaźnik, wyrzucając losowe śmieci, które zdarzyły się zawierać "*" otoczony spacją do bufora używanego dla nazwy ... i skryptu powłoki iterującego po nazwach plików w celu starzenia się z systemu zapasowego, a następnie usuniętego *wszystko*). –

0
VBoxManage list runningvms | sed 's/"//g;s/ .*//' 

pętli:

for machine in `VBoxManage list runningvms | sed 's/"//g;s/ .*//'` ; do 
    echo $machine 
done 

będzie to przebić, jeśli urządzenie ma spacji w nazwie.

+0

Zobacz [Nie czytaj linii z tekstem] (http://mywiki.wooledge.org/DontReadLinesWithFor) –

15
VBoxManage list runningvms | cut -d '"' -f 2 | while read machine; do 
    echo "$machine" 
done 
+1

To lepsze niż moje - moje zawiedzie, jeśli nazwa obrazu zawiera spacje ... nie myślał o tym . – Mat

+1

Składnia 'while read ... do' jest dokładnie tym, czego szukałem! – Kyrstellaine

+1

Możesz wyciąć 'cut', pisząc' while IFS = "" "read _ machine _; do'. –

2

dla fanów jednego liniowej:

VBoxManage list runningvms | cut -d" " -f 1 | grep -oP "(?<=\").*(?=\")" 
1

Aby potwierdzić każdą linię, jak je czytać, bezpieczny sposób, aby to zrobić, to napisać wyrażenie regularne i użyć BASH_REMATCH wyodrębnić grupy meczu z niej .

z następującego kodu:

re='^"(.*)" [{]([0-9a-f-]+)[}]$' 
while read -r line; do 
    if [[ $line =~ $re ]]; then 
    name=${BASH_REMATCH[1]}; uuid=${BASH_REMATCH[2]} 
    echo "Found VM with name $name and uuid $uuid" >&2 
    else 
    echo "ERROR: Could not parse line: $line" >&2 
    fi 
done < <(VBoxManage list runningvms) 

... i następnego udawanym realizacji VBoxManage (aby umożliwić ludzie bez VirtualBox odtworzyć test):

VBoxManage() { printf '%s\n' '"UbuntuServer" {7ef01f8d-a7d5-4405-af42-94d85f999dff}'; } 

... wyjście w następujący sposób:

Found VM with name UbuntuServer and uuid 7ef01f8d-a7d5-4405-af42-94d85f999dff 

Uwaga Zalety tego podejścia:

  • Nie zawiera nieuzasadnionych założeń, takich jak wykluczenie maszyn wirtualnych z białymi znakami lub literałów cudzysłowu w ich nazwach z poziomu wsparcia.
  • Wykrywa każdą linię, która nie pasuje do oczekiwanego wzorca, zamiast zachowywać się nieprzewidywalnie w obecności takich wartości.
  • To nadal działa poprawnie z danymi, które ma pasuje do wzorca, ale ma nieprzewidziane wartości. (Na przykład maszyna wirtualna o nazwie * nie będzie miała cichej nazwy zastąpionej nazwą pliku w bieżącym katalogu).
  • To nie wymaga zewnętrznych narzędzi do powłoki, takie jak sed, cut, & c, ale opiera się wyłącznie na muszli wbudowane funkcjonalności. - patrz BashFAQ #1 dokumentowania użycia while read i the bash-hackers' wiki on regular expression matching dokumentowania [[ $string =~ $re ]].
Powiązane problemy