How to let Linux scripts detect that they are running on virtual machines

0
23


diy13 / Shutterstock.com

Virtual machines go to great lengths to convince their operating systems that they are running on physical hardware. So can you tell from the Linux command line if the computer is physical or virtual?

Virtual machines and hypervisors

A traditional computer is a physical object. It’s a collection of different pieces of hardware that plug and play together so you can load an operating system, install apps, run them, and use them.

Hardware is expensive. Being restricted to one operating system per physical computer means that the cost of running multiple operating systems soon becomes prohibitive. A better solution would be to allow a single physical computer to run a selection of operating systems at the same time, with each thinking that it is running on its own unique hardware.

A hypervisor makes it possible. A hypervisor, also called a virtual machine manager or virtual machine monitor, is software that allows you to create virtual machines. These behave as if they were individual physical computers, although they run on the same physical host, sharing their hard drive space, memory, and CPU cores.

Of course, the host computer must be powerful enough to handle the demands of the virtual machine collection, but with enough RAM and processing power on the host, the virtual machines can run at near full speeds.

Since the release of kernel 2.6.20 in 2007, Linux has had kkernel-based vvirtual METER.The machine support was baked directly. Linux has several hypervisors available, such as VirtualBox, GNOME Boxes, and QEMU-KVM. They make use of the native KVM capability of Linux, building on the functionality of the native kernel by adding user interfaces and functionality such as the ability to take a snapshot of a virtual machine.

Virtual machines provide cost savings, efficiencies, simplified deployments and, if provisioned correctly, security benefits. They also facilitate scalability. New servers can automatically turn on as demand for a service increases and turn off when demand decreases. This makes them very popular both in the cloud and on-premises infrastructure.

Maybe you’re remotely managing a Linux server and need to know if it’s a virtual machine or a physical box. Or you have a script that needs to know what kind of platform it’s running on. Here are several ways you can detect if the computer you are working on is physical or virtual.

The dmicode command

The dmidecode The command supports a large number of options and switches. Query the Desktop Management Interface (DMI) tables and print the information to the terminal window.

We will use it with -s (display a single string) and prompt for the system product name. Note that we must use sudo.

We will execute the command in a VirtualBox virtual machine with Ubuntu 22.04.

sudo dmidecode -s system-product-name

The dmidecode command that correctly identifies a VirtualBox virtual machine

The platform is correctly identified as VirtualBox.

On a QEMU-KVM virtual machine running Fedora 35, we get this output.

sudo dmidecode -s system-product-name

The dmidecode command that correctly identifies a GNOME Boxes VM

Although this is reported as a standard PC, it is a standard QEMU virtual PC, type Q35. Then the platform is correctly recognized as a virtual machine.

If we run the same command on a physical computer, we get information about the manufacturer.

sudo dmidecode -s system-product-name

The dmidecode command that returns information about a physical computer

This computer is a custom build based on a Micro-Star International Company Limited motherboard, with the product code of MS-7B86.

The lshw command

The lshw The command lists the details of a wide range of computer hardware. We can choose what kind of hardware we want lshw to inform.

we are going to use the -class option with system modifier Using sudo with this command it ensures that we see all the details.

We will execute this command in our Ubuntu VirtualBox virtual machine.

sudo lshw -class system

The lshw command reporting on a VirtualBox virtual machine

  • The “description” field has a generic entry of “computer”.
  • The “product” field tells us that this is a virtual machine running on VirtualBox.
  • The “vendor” field contains the name of the German company that created VirtualBox, Innotek GmbH. Innotek was acquired by Oracle Corporation in 2010 as part of its acquisition of Sun Microsystems, Inc.

we had to install lshw in fedora.

sudo dnf install lshw

Install lshw on Fedora with the dnf command

Let’s try that command on our Fedora VM running in GNOME Boxes.

sudo lshw -class system

The lshw command reports a GNOME Boxes VM

  • Again, the “description” field has a generic entry of “computer”.
  • The “product” field gives us the same standard QEMU PC information that we saw with the dmidecode domain.
  • The “vendor” field contains “QEMU”, which clearly indicates that it is a virtual machine.

This is the result of running the same command on our physical computer.

sudo lshw -class system

The lshw command reporting on a physical computer

We can see that it is a hardware computer, with a Micro-Star motherboard.

  • The hardware is identified as a desktop computer.
  • The “product” field gives us the type of motherboard, MS-7B86.
  • The “vendor” field contains the name of the manufacturer.

The hostnamectl command

This command has the advantage that you do not need to have sudo privileges to run it. However, it is only available in systemdenabled distributions. Most modern distributions use systemd.

This is the response when running the command in our Ubuntu VirtualBox virtual machine.

hostnamectl

The output of the hostnamectl command on a VirtualBox virtual machine with the virtualization line highlighted

  • The “icon-name” field has “-vm” appended to it.
  • The “Chassis” field contains “vm”.
  • The “Virtualization” field contains “oracle”.
  • The “Hardware Provider” field contains “innotek GmbH”.
  • The “Hardware Model” field contains “VirtualBox”.

The result of our Fedora VM inside GNOME Boxes is very similar.

hostnamectl

The output of the hostnamectl command on a GNOME Boxes VM with the virtualization line highlighted

  • The “icon-name” field has “-vm” appended to it.
  • The “Chassis” field contains “vm”.
  • The “Virtualization” field contains “kvm”.
  • The “Hardware Vendor” field contains “QEMU”
  • The “Hardware Model” field contains “Standard PC (Q35 + ICH9, 2009)”.

If we use the hostnamectl command on our physical desktop, the output does not contain a “Virtualization” line.

hostnamectl

The output of the hostnamectl command on a physical computer, with no host information

If there is no “Virtualization” field, you must be running bare metal.

The systemd-detect-virt command

If you want to get as short an answer as possible, systemd-detect-virt is probably what you are looking for. Again this requires a systemd-distribution equipped, but not required sudo privileges This, and its terse output, make it well suited for use in scripts.

This is the result of running the command on our Ubuntu VirtualBox virtual machine.

systemd-detect-virt

Identifying a VirtualBox virtual machine with systemd-detect-virt

Our copy of Fedora running on GNOME Boxes is reported to use KVM virtualization.

systemd-detect-virt

Identifying a GNOME Boxes VM with systemd-detect-virt

In a hurry systemd-detect-virt on our hardware machine results in “none” being printed to the terminal.

systemd-detect-virt

A physical computer that was correctly identified as not having virtualization

A platform-aware script

To give a script the ability to detect whether it is running in a virtualized environment or on physical hardware, we can use the systemd-detect-virt Bash command and usage case statements to handle options.

This is the script we will use. Copy this text and save it to a file called “platform.sh”.

#!/bin/bash

shopt -s nocasematch

case $(systemd-detect-virt) in

  none)
    echo "Physical Hardware"
    ;;

  *)
    echo "Virtual Machine"
    ;;
esac

The script uses shopt to choose matches that are not case sensitive. The systemd-detect-virt The command is used in case statement. The output of this command is compared with each of the case clauses in the body of the case statement until a match is found. Anything that doesn’t match is captured by the default “*)” clause.

The simplest way is to test if the answer of systemd-detect-virt is “none”. If so, the script is running on physical hardware. For all other cases, the script must be run on a virtual machine.

Before we can run the script, we need to make it executable, using chmod.

chmod +x platform.sh

Make platform script executable with chmod

It correctly identifies our Ubuntu VirtualBox virtual machine as a virtual machine.

./platform.sh

Using the platform.sh script in a VirtualBox VM

It also correctly detects the GNOME Boxes virtual machine running Fedora.

./platform.sh

Using the platform.sh script in a GNOME Boxes VM

The script also correctly detects when it is running on a physical machine.

./platform.sh

Using the platform.sh script on a physical computer

the different case The clauses could set variables that were checked elsewhere in the script to perform different types of processing, or they could call specific functions within your script.

If your script needed to detect and accommodate different types of virtual environments, you could add more case clauses, looking for the different strings that systemd-detect-virt can return We can see the full list of possible answers using the --list option. To make it easier to see them all at once, we’ll pipe the output through the column domain.

systemd-detect-virt --list | column

The full set of responses that systemd-detect-virt can return

take the red pill

These techniques let your scripts know when they are running on bare hardware and when they are inside a virtual machine.

Like Neo in the Matrix, they will know what is real and what is not.