【问题标题】:Trim table of text and store values as variables修剪文本表并将值存储为变量
【发布时间】:2018-12-02 08:37:36
【问题描述】:

我正在尝试编写一个可以在我的 FreeNas (FreeBSD) 机器上运行的脚本,该脚本通过 SSH 连接到 ESXi 主机并正常关闭 VM。我需要为 VM ID 列表运行的是:

vim-cmd vmsvc/power.shutdown VMID

在过滤用于检索 ID 的命令的输出,然后将其传递给关闭命令的一些帮助之后。

检索所有虚拟机的命令是:

vim-cmd vmsvc/getallvms

它输出这样的数据:

Vmid     Name                          File                             Guest OS          Version   Annotation
12     Eds-LINUX   [Eds-FS-Datastore-1] Eds-LINUX/Eds-LINUX.vmx   ubuntu64Guest           vmx-13
13     Eds-RT      [Eds-FS-Datastore-1] Eds-RT/Eds-RT.vmx         freebsd64Guest          vmx-13
14     Eds-DC      [Eds-FS-Datastore-1] Eds-DC/Eds-DC.vmx         windows9Server64Guest   vmx-13
15     Eds-STEAM   [Eds-FS-Datastore-1] Eds-STEAM/Eds-STEAM.vmx   windows9_64Guest        vmx-13
16     Eds-DL      [Eds-FS-Datastore-1] Eds-DL/Eds-DL.vmx         windows9Server64Guest   vmx-13
17     Eds-RD      [Eds-FS-Datastore-1] Eds-RD/Eds-RD.vmx         windows9Server64Guest   vmx-13
18     Eds-PLEX    [Eds-FS-Datastore-1] Eds-PLEX/Eds-PLEX.vmx     windows9Server64Guest   vmx-13
19     Eds-MC      [Eds-FS-Datastore-1] Eds-MC/Eds-MC.vmx         windows9Server64Guest   vmx-13
2      Eds-FS      [Eds-ESXi-Datastore-1] Eds-FS/Eds-FS.vmx       freebsd64Guest          vmx-13

我已经确定我可以使用管道进入 sed,删除第一行,使用:

vim-cmd vmsvc/getallvms | sed '1d'

然后我可以使用以下方法检索我要过滤掉的 VM 的 ID:

vim-cmd vmsvc/getallvms | awk '/Eds-FS.vmx/{print$1}'

这给了我 2 的 ID。但是我不清楚如何将它存储在变量中以备后用。

我需要知道一种从该数据中仅选择第一列的方法,并将列表中的每个 ID 放入一个数组中。然后我需要遍历数组并为每个 ID 运行以下命令以获取 VM 的电源状态:

vim-cmd vmsvc/power.getstate VMID

这样输出数据,状态为开机或关机:

Retrieved runtime info
Powered on

对于每一个被打开的虚拟机,我需要将虚拟机 ID 存储在第二个数组中,以便稍后传递给关闭命令,除非 ID 等于我要关闭的虚拟机的 ID .

【问题讨论】:

    标签: linux shell ssh sh


    【解决方案1】:

    感谢 anubhava,他为我提供了足够的帮助以使某些东西正常工作(尽管可能没有遵循标准或最佳实践)

    我将此脚本保存在我的 ESXi 主机上,我通过 SSH 连接到该主机并触发运行:

    freenasid=`vim-cmd vmsvc/getallvms | sed '1d' | awk '/Eds-FS.vmx/{print$1}'`
    vmids=`vim-cmd vmsvc/getallvms | sed '1d' | awk '{print$1}'`
    for vmid in $vmids
    do
    if [ $vmid != $freenasid ]
    then
    powerstate=`vim-cmd vmsvc/power.getstate $vmid | sed '1d'`
    if [ "$powerstate" = "Powered on" ]
    then
    onvmids="$onvmids $vmid"
    fi
    fi
    done
    for vmid in $onvmids
    do
    vim-cmd vmsvc/power.shutdown $vmid
    done
    exit 0
    

    这会正确关闭所有正在运行的虚拟机。

    【讨论】:

      【解决方案2】:

      要列出第一列中的 ID,请使用 awk,如下所示:

      vim-cmd vmsvc/getallvms | awk 'NR>1{print $1}'
      

      要将 ID 存储在 shell 数组中,请使用:

      readarray -t arr < <(vim-cmd vmsvc/getallvms | awk 'NR>1{print $1}')
      

      遍历数组并运行另一个命令:

      for id in "${arr[@]}"; do
         vim-cmd vmsvc/power.getstate "$id"
      done
      

      要存储一个特定的 id 使用命令替换:

      vmid1=$(vim-cmd vmsvc/getallvms | awk '/Eds-FS\.vmx/{print$1}')
      

      【讨论】:

      • 谢谢。执行 readarray 时,出现语法错误“意外重定向”?
      • 我明白了。关于在 ESXi 上创建数组的另一种方法有什么想法吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-13
      • 1970-01-01
      相关资源
      最近更新 更多