How do you allow Linux scripts to detect that they are running in virtual machines?

Virtual machines do their best to convince their operating system that they are running on physical machines. So can you tell if a computer is physical or virtual from the Linux command line?

Virtual machines and hypervisors

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

Expensive materials. Being restricted to one operating system per physical computer means that the cost of running multiple operating systems quickly becomes prohibitive. A better solution might be to allow a single physical computer to run a selection of operating systems at the same time, each of which believes it is running on its own hardware.

Hypervisor makes this possible. A hypervisor, also known as a virtual machine manager or virtual machine monitor, is a program that allows you to create virtual machines. These behave as if they were individual physical computers, even though they run on the same physical host, which share hard disk space, memory, and a kernel processor.

Of course, the host computer must be powerful enough to meet the requirements of all virtual machines, but if the host’s RAM and processing power are sufficient, virtual machines can operate at speeds close to the speed of bare machines.

Since kernel 2.6.20 was released in 2007, Linux has integrated kernel-based virtual machine support. Linux has many hypervisors, such as VirtualBox, GNOME Boxes, and QEMU-KVM. They use Linux’s native KVM capability, building on native kernel functionality to add user interfaces and features such as the ability to take a snapshot of a virtual machine.

Virtual machines save money, gain efficiency, simplify deployments and, if properly provisioned, provide security benefits. It also facilitates scalability. New servers can be provisioned automatically when demand for a service increases and shut down when demand is low. This is what makes them so popular, both in the cloud and in on-premises infrastructures.

You might be running a Linux server remotely 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 to detect if the computer you’re working on is physical or virtual.

How to use SET AND PIPEFAIL in Bash scripts on LINUX

dmidecode . command

The dmidecode command supports a large number of options and modifiers. Queries for Desktop Management Interface (DMI) tables and displays information in the Terminal window.

We will use it with the -s option (display one string), and ask for the name of the system product. Note that we have to use sudo.

We will be running the command on a VirtualBox VM running Ubuntu 22.04.

sudo dmidecode -s System product name

The dmidecode command correctly identifies the VirtualBox VM

The platform is correctly identified as VirtualBox.

We get this output in QEMU-KVM running Fedora 35.

sudo dmidecode -s System product name

The dmidecode command correctly identifies the GNOME Boxes VM

Although marked as a standard PC, it is a standard QEMU virtual PC, type Q35. So the platform is correctly recognized as a virtual machine.

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

sudo dmidecode -s System product name

The dmidecode command returns information about a physical computer

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

HOW TO USE THE GETOPTS TOOL TO ANALYZE SCRIPTS SHELL LINUX OPTIONS

command lsw

The lshw command lists details of a large group of computers. We can choose the category of devices we want lshw to report on.

We will use the -class option with the system modifier. Using sudo with this command ensures that we see all the details.

We will be running this command on our Ubuntu VirtualBox VM.

sudo lshw-class system

Report on the lshw command on VirtualBox VM

Le champ "description" contient une entrée générique "ordinateur".
Le champ "product" nous indique qu'il s'agit d'une machine virtuelle exécutée dans VirtualBox.
Le champ "vendor" contient le nom de la société allemande qui a créé VirtualBox, Innotek GmbH. Innotek a été rachetée par Oracle Corporation en 2010 dans le cadre de son acquisition de Sun Microsystems, Inc.

We had to install lshw on Fedora.

sudo dnf install lshw

Install lshw on Fedora using the dnf الأمر command

Let’s try this out in Fedora VM running in GNOME boxes.

sudo lshw-class system

Report on the lshw command on the GNOME Boxes VM

Une fois encore, le champ "description" contient une entrée générique "ordinateur".
Le champ "product" nous donne les mêmes informations standard sur le PC QEMU que nous avons vues avec la commande dmidecode.
Le champ "vendor" contient "QEMU" qui indique clairement qu'il s'agit d'une machine virtuelle.

Here is the result of running the same command on our computer.

sudo lshw-class system

Report on the lshw command on a physical computer

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

Le matériel est identifié comme étant un ordinateur de bureau.
Le champ "product" nous donne le type de carte mère, MS-7B86.
Le champ "vendor" contient le nom du fabricant.

hostnamectl . command

This command has the advantage that it does not require sudo privileges to run. However, it is only available on systemd compatible distributions. Most modern distributions use systemd.

This is the response from running the command on our Ubuntu VirtualBox VM.

Hostnamekl

Output the hostnamectl command in VirtualBox VM with the virtualization line highlighted.

Le champ "icon-name" a "-vm" ajouté à celui-ci.
Le champ "Chassis" contient "vm".
Le champ "Virtualization" contient "oracle".
Le champ "Hardware Vendor" contient "innotek GmbH".
Le champ "Hardware Model" contient "VirtualBox".

The output in our Fedora VM in GNOME boxes is very similar.

Hostnamekl

Output the hostnamectl command in the GNOME Boxes VM with the virtualization line highlighted.

Le champ "icon-name" est complété par "-vm".
Le champ "Chassis" contient "vm".
Le champ "Virtualization" contient "kvm".
Le champ "Hardware Vendor" contient "QEMU".
Le champ "Hardware Model" contient "Standard PC (Q35 + ICH9, 2009)".

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

Hostnamekl

Output of the hostnamectl command on a physical computer, without the “Virtualization” information.

If there is no “virtual” field, you should work on bare metal.

systemd-det-virt . command

If you want to keep the answer as short as possible, the systemd-det-virtue command is probably what you’re looking for. Again, this command requires a systemd-equipped distro, but it does not require sudo privileges. This, along with its succinct output, makes it well suited for use in scripts.

Here is the result of running the command on our Ubuntu VirtualBox VM.

systemd-reveal-virtue

Getting to know the VirtualBox VM using systemd-det-virt

Our version of Fedora running on GNOME boxes is reported as using KVM virtualization.

systemd-reveal-virtue

Getting to know the GNOME Boxes VM using systemd-det-virt

Running systemd-discovery-virt on our device causes ‘Nothing’ to appear in the device.

systemd-reveal-virtue

A physical computer is correctly identified as having no virtualization.

Platform aware script

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

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

! / bin / bash

shopt -s nocasematch

case $ (systemd-det-virt) in

no one)
echo “physical hardware”
; ;

*)
echo “virtual machine” ;; ; *)
; ;
esac

The shopt script is used to choose a case insensitive match. The systemd-detect-virt command is used in the status statement. The output of this command is compared to each case clause in the case statement body until a match is found. Anything that doesn’t match the default “*)” statement is captured.

The easiest way is to test if the response from systemd-det-virtue is “none”. If so, the script will run 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 the platform script executable with chmod

It correctly sets our Ubuntu VirtualBox VM as the virtual machine.

./platform.sh

Using the platform.sh script in VirtualBox VM

It also correctly detects the GNOME Boxes VM that is running Fedora.

./platform.sh

Using the platform.sh script in GNOME Boxes VM

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

./platform.sh

Using the platform.sh script on a physical computer

Different case statements can define variables that are checked elsewhere in the script to perform different types of processing, or they can call specific functions in your script.

If your script needs to detect and compute different types of virtual environments, you can add more case statements, and search for different strings that systemd-discovery-virt might return. We can see the full list of possible answers using the –list option. To make it easier to view all responses at once, we’ll pass the output through the column command.

Virtue detection system | vertical

The full set of responses that systemd-det-virtue can return.

Take the red pill

These technologies let your scripts know when they are playing on bare metal and when they are in a virtual machine.

Like Neo in The Matrix, they’ll know what’s real and what’s not.

Frank Mccarthy

<p class="sign">"Certified gamer. Problem solver. Internet enthusiast. Twitter scholar. Infuriatingly humble alcohol geek. Tv guru."</p>

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top