2011-08-15 40 views
15

我想遍歷我正在運行的虛擬機,並只返回引號之間的內容。使用VBoxManage獲取正在運行的虛擬機列表

所以這個命令:

VBoxManage list runningvms 

回報:

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

,我只希望它返回:

UbuntuServer 

這是我迄今爲止(失敗):

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

回答

16

警告:如果您的VM名稱中包含shell全局字符或包含空格,則所有這些都是有風險的。


你可以做這樣的事情,如果只有一個正在運行的VM:

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

替代使用bash陣列(同等條件下):

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

如果該程序返回多一條線,更經典的做法是:

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

「經典方法」是不好的做法,因爲'array =($(...))'方法;例如,兩者都將用當前目錄中的文件列表替換輸入中的單個標記「*」。請參見[不要閱讀用於](http://mywiki.wooledge.org/DontReadLinesWithFor),[BashPitfalls#50](http://mywiki.wooledge.org/BashPitfalls#hosts.3D.28_.24.28aws_ ... 29_.29)和[BashFAQ#1](http://mywiki.wooledge.org/BashFAQ/001) –

+0

需要對此特定示例進行單詞分割,並且似乎不太可能匹配全局模式的VM名稱。 – Mat

+0

我發生的最糟糕的數據丟失事件發生是因爲有人忽略了一個「不可能」的事件(一個程序創建文件「不可能」創建任何不匹配[0-9a-f] {24}的東西;一個錯誤在一個第三方庫中損壞了一個指針,將隨機垃圾傾倒到用於名稱的緩衝區中,其中包含一個空白包圍的'*'......並且一個shell腳本遍歷文件名以超過備份系統,然後被刪除*一切*)。 –

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

要遍歷:

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

這將打破,如果你的機器有空格的名稱。

+0

請參閱[不要閱讀線條](http://mywiki.wooledge.org/DontReadLinesWithFor) –

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

這比我的好 - 如果圖像名稱中有空格,我的圖像名稱會失敗......沒有想過這個。 – Mat

+1

'while read ... do'語法正是我所期待的! – Kyrstellaine

+1

你可以通過書寫''cut'來取出'while'IFS ='''read _ machine _; do'。 –

2

一班輪球迷:

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

爲了驗證每一行,你讀它,安全的方式做到這一點是寫一個正則表達式,並使用BASH_REMATCH從中提取的匹配組。

用下面的代碼:

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) 

...和下​​面的模擬實現VBoxManage的(以允許無VirtualBox的人重現性試驗):

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

...輸出是如下:

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

注意這種方法的優點:

  • 它沒有做出毫無根據的假設,例如從支持名稱中排除名稱中帶有空格或引號的虛擬機。
  • 它檢測到任何與預期模式不匹配的行,而不是在存在這些值時以不可預料的方式運行。
  • 它仍然正確與確實符合模式,但具有意想不到的值。 (例如,名爲*的虛擬機將不會將該名稱靜默地替換爲當前目錄中文件的名稱)。
  • 它不涉及外部殼體,如sedcut,&Ç工具,但殼內置功能完全依賴 - 見BashFAQ #1記錄使用while readthe bash-hackers' wiki on regular expression matching記錄[[ $string =~ $re ]]