如何讓 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 | 柱子
服用紅色藥丸
這些技術讓您的腳本知道它們何時在裸硬件上運行以及它們何時在虛擬機中。
就像黑客帝國中的尼奧一樣,他們會知道什麼是真實的,什麼不是。