如何让 Linux 脚本检测它们在虚拟机中运行
已发表: 2022-06-27虚拟机非常努力地试图让它们的操作系统相信它们是在物理硬件上运行的。 那么你能从 Linux 命令行中分辨出计算机是物理的还是虚拟的?
虚拟机和管理程序
传统计算机是物理对象。 它是一组不同的硬件,它们插在一起并用螺栓固定在一起,以便您可以加载操作系统、安装应用程序、启动它们并使用它们。
硬件很贵。 每台物理计算机仅限于一个操作系统意味着运行多个操作系统的成本很快就会变得过高。 更好的解决方案是允许一台物理计算机同时运行一系列操作系统,每个操作系统都认为它运行在自己独特的硬件中。
管理程序使这成为可能。 管理程序(也称为虚拟机管理器或虚拟机监视器)是允许您创建虚拟机的软件。 尽管它们在同一物理主机上运行,共享其硬盘空间、内存和 CPU 内核,但它们的行为就好像它们是单独的物理计算机。
当然,主机必须足够强大才能满足虚拟机集合的需求,但是,如果主机中有足够的 RAM 和处理能力,虚拟机可以以接近裸机的速度运行。
自 2007 年发布2.6.20内核以来,Linux 已经内置了基于内核的虚拟机支持。Linux有几个可用的管理程序,例如 VirtualBox、GNOME Boxes 和QEMU -KVM。 他们利用 Linux 的本机 KVM 功能,通过添加用户界面和功能(例如能够拍摄虚拟机的快照)来构建本机内核功能。
虚拟机带来成本节约、效率、简化部署以及正确配置的安全优势。 它们还有助于可扩展性。 新服务器可以随着对服务的需求增加而自动启动,并在需求下降时关闭。 这使得它们在云和本地基础设施中都非常受欢迎。
也许您正在远程管理 Linux 服务器,您需要知道它是虚拟机还是物理机。 或者你有一个脚本需要知道它在什么类型的平台上执行。 您可以通过以下几种方法检测您正在使用的计算机是物理计算机还是虚拟计算机。
dmidecode 命令
dmidecode
命令支持大量选项和修饰符。 它询问桌面管理界面 (DMI) 表,并在终端窗口中打印信息。
我们将它与-s
(显示单个字符串)选项一起使用,并询问系统产品名称。 请注意,我们必须使用sudo
。
我们将在运行 Ubuntu 22.04 的 VirtualBox VM 上运行该命令。
sudo dmidecode -s 系统产品名称
该平台被正确识别为 VirtualBox。
在运行 Fedora 35 的 QEMU-KVM VM 上,我们得到了这个输出。
sudo dmidecode -s 系统产品名称
尽管这是作为标准 PC 报告的,但它是 Q35 类型的标准 QEMU 虚拟 PC。 因此该平台被正确识别为虚拟机。
如果我们在物理计算机上运行相同的命令,我们会得到一些关于制造商的信息。
sudo dmidecode -s 系统产品名称
该电脑是基于微星国际有限公司主板定制的,产品代码为MS-7B86。
lshw 命令
lshw
命令列出了各种计算机硬件的详细信息。 我们可以选择希望lshw
报告的硬件类别。
我们将使用带有system
修饰符的-class
选项。 将此命令与sudo
一起使用可确保我们看到所有详细信息。
我们将在我们的 Ubuntu VirtualBox VM 上运行此命令。
sudo lshw - 类系统
- “描述”字段有一个通用条目“计算机”。
- “产品”字段告诉我们这是在 VirtualBox 中运行的虚拟机。
- “供应商”字段包含创建 VirtualBox 的德国公司 Innotek GmbH 的名称。 Innotek 于 2010 年被甲骨文公司收购,作为其收购 Sun Microsystems, Inc. 的一部分。
我们必须在 Fedora 上安装lshw
。
须藤 dnf 安装 lshw
让我们在 GNOME Boxes 中运行的 Fedora VM 中尝试该命令。
sudo lshw - 类系统
- 同样,“描述”字段具有“计算机”的通用条目。
- “product”字段为我们提供了与使用
dmidecode
命令看到的相同的标准 QEMU PC 信息。 - “vendor”字段包含“QEMU”,它非常清楚地表明这是一个虚拟机。
这是在我们的物理计算机上运行相同命令的结果。
sudo lshw - 类系统
我们可以看到这是一台硬件电脑,主板是微星。
- 该硬件被标识为台式计算机。
- “产品”字段为我们提供了主板类型 MS-7B86。
- “供应商”字段包含制造商的名称。
hostnamectl 命令
此命令的优点是您无需具有sudo
权限即可运行它。 但是,它仅在启用systemd
的发行版上可用。 大多数现代发行版都使用systemd
。
这是在我们的 Ubuntu VirtualBox VM 上运行命令的响应。
主机名
- “icon-name”字段附加了“-vm”。
- “机箱”字段包含“vm”。
- “虚拟化”字段包含“oracle”。
- “硬件供应商”字段包含“innotek GmbH”。
- “硬件模型”字段包含“VirtualBox”。
我们在 GNOME Boxes 中的 Fedora VM 上的输出非常相似。
主机名
- “icon-name”字段附加了“-vm”。
- “机箱”字段包含“vm”。
- “虚拟化”字段包含“kvm”。
- “硬件供应商”字段包含“QEMU”
- “硬件型号”字段包含“标准 PC (Q35 + ICH9, 2009)”。
如果我们在物理桌面上使用 hostnamectl 命令,输出不包含“虚拟化”行。
主机名
如果没有“虚拟化”字段,则您必须在裸机上运行。
systemd-detect-virt 命令
如果您想获得尽可能简短的答案, systemd-detect-virt
可能就是您要找的。 同样,这需要一个配备systemd
的发行版,但它不需要sudo
权限。 这——以及它的简洁输出——使它非常适合在脚本中使用。
这是在我们的 Ubuntu VirtualBox VM 上运行命令的结果。
systemd-检测-virt
据报道,我们在 GNOME Boxes 中运行的 Fedora 副本使用了 KVM 虚拟化。
systemd-检测-virt
在我们的硬件机器上运行systemd-detect-virt
会导致终端打印“none”。
systemd-检测-virt
平台敏感的脚本
为了让脚本能够检测它是在虚拟化环境中还是在物理硬件上运行,我们可以使用systemd-detect-virt
命令并使用 Bash case
语句来处理选项。
这是我们将使用的脚本。 复制此文本并将其保存到名为“platform.sh”的文件中。
#!/bin/bash shopt -s nocasematch 案例 $(systemd-detect-virt) 在 没有任何) 回声“物理硬件” ;; *) 回声“虚拟机” ;; 经社理事会
该脚本使用shopt
选择不区分大小写的匹配。 在case
语句中使用systemd-detect-virt
命令。 将此命令的输出与case
语句主体中的每个case
子句进行比较,直到找到匹配项。 “*)”默认子句捕获任何不匹配的内容。
最简单的方法是测试来自systemd-detect-virt
的响应是否为“无”。 如果是,则脚本在物理硬件上运行。 对于所有其他情况,脚本必须在虚拟机上运行。
在我们可以运行脚本之前,我们必须使用chmod
使其可执行。
chmod +x 平台.sh
它正确地将我们的 Ubuntu VirtualBox VM 识别为虚拟机。
./平台.sh
它还可以正确检测运行 Fedora 的 GNOME Boxes VM。
./平台.sh
该脚本还可以正确检测它何时在物理机上运行。
./平台.sh
不同的case
子句可以设置在脚本其他地方检查的变量以执行不同类型的处理,或者它们可以调用脚本中的特定函数。
如果您的脚本需要检测和适应不同类型的虚拟环境,您可以添加更多case
子句,寻找systemd-detect-virt
可以返回的不同字符串。 我们可以使用--list
选项查看可能响应的完整列表。 为了更容易一次看到它们,我们将通过column
命令管道输出。
systemd-detect-virt --list | 柱子
服用红色药丸
这些技术让您的脚本知道它们何时在裸硬件上运行以及它们何时在虚拟机中。
就像黑客帝国中的尼奥一样,他们会知道什么是真实的,什么不是。