使用 VBoxManage 获取正在运行的虚拟机列表

问题描述 投票:0回答:6

我想循环遍历正在运行的虚拟机并仅返回引号之间的内容。

所以这个命令:

VBoxManage list runningvms

返回:

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

我只希望它返回:

UbuntuServer

这就是我到目前为止所拥有的(失败):

#!/bin/bash
for machine in `cat VBoxManage list runningvms`; do
        echo "$machine"
done
exit
bash virtualbox
6个回答
18
投票
VBoxManage list runningvms | cut -d '"' -f 2 | while read machine; do
   echo "$machine"
done

16
投票

警告:如果您的虚拟机名称中包含 shell glob 字符或包含空格,那么所有这些都是有风险的。


如果只有一个正在运行的虚拟机,您可以执行以下操作:

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

2
投票

对于单线粉丝:

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

2
投票

要在阅读时验证每一行,安全的方法是编写正则表达式并使用

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

注意这种方法的优点:

  • 它不会做出毫无根据的假设,例如从支持中排除名称中带有空格或引号文字的虚拟机。
  • 它会检测任何与预期模式不匹配的行,而不是在存在此类值时以意外的方式运行。
  • 对于那些确实匹配模式但具有意外值的数据,它仍然可以正确运行。 (例如,名为
    *
    的虚拟机不会将该名称默默地替换为当前目录中的文件名)。
  • 它不涉及 shell 外部的工具,例如
    sed
    cut
    等,但纯粹依赖于 shell 内置功能 - 请参阅 BashFAQ #1 记录
    while read
    的使用,以及 bash-hackers' wiki 关于正则表达式匹配 记录
    [[ $string =~ $re ]]

2
投票
VBoxManage list runningvms|awk -F \{ '{gsub("\"",""); print $1}'

对于

VBoxManage
输出中的每一行,这会删除
"
字符,然后打印第一个字段(当使用
{
作为字段分隔符时,它会启动 vbox 虚拟机的 UID)。

无需检查空格或以不同方式处理输出的任何部分,也无需执行除转义特殊字符之外的任何 shell 操作。

我发现 awk

cut
grep
sed
等更通用,而且也更具表现力。它自 1987 年以来一直存在,自 1992 年起成为 POSIX 标准:您的系统上更有可能有
awk
,而不是
bash


编辑 2024-09-30:重新审视这一点时,此输出不需要字段分隔符

-F \{
,因为默认分隔符是空格,并且名称和 UID 之间已经有空格。

VBoxManage list runningvms|awk '{gsub("\"",""); print $1}'

1
投票
VBoxManage list runningvms | sed 's/"//g;s/ .*//'

循环浏览:

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

如果你的机器名称中有空格,这将会中断。

© www.soinside.com 2019 - 2024. All rights reserved.