In modern cloud engineering, DevOps automation, and fleet systems administration, shell scripts and deployment pipelines must frequently adapt their execution based on the underlying hardware environment. For example, an administrative script provisioning an Ubuntu system may need to skip hardware microcode updates or physical RAID monitoring tools when executing inside a cloud virtual machine (VM), or bypass systemd service daemon controls when executing inside an isolated application container. While inspecting /proc/cpuinfo, DMI tables via dmidecode, or lspci outputs requires parsing text heuristically, Ubuntu includes the purpose-built systemd-detect-virt binary. This tool delivers fast, exit-code-driven identification of hypervisors and container technologies directly from the command line.
How systemd-detect-virt Identifies Virtual Platforms
The systemd-detect-virt utility inspects CPU hypervisor flags, ACPI tables, SMBIOS hardware strings, and container namespace identifiers:
- Hardware Virtualization (Hypervisors): Detects hardware-assisted hypervisors by querying the CPUID instruction for hypervisor feature bits and reading vendor strings (e.g. KVM, QEMU, VMware, Hyper-V, Xen, VirtualBox, and Apple Virtualization Framework).
- Operating System Containers: Detects container environments by inspecting
/proc/1/environ(such ascontainer=environment variables), cgroup mount hierarchies, and namespace isolations (e.g. Docker, Podman, LXC, systemd-nspawn, OpenVZ, and Kubernetes containerd). - Exit Code Logic: Returns exit code
0when executing inside a virtualized or container environment, and exit code1(non-zero) when executing on bare-metal physical hardware.
Basic Execution and Environment Output
To inspect the virtualization layer of an Ubuntu system, execute the command without parameters:
# Detect the active virtualisation environment
systemd-detect-virt
The output reports the specific hypervisor or container technology name:
# Output example on an AWS EC2 instance or Proxmox VM:
kvm
# Output example inside a Docker or Podman container:
docker
# Output example on a bare-metal physical server:
none
Distinguishing Between Virtual Machines and Containers
By default, if an Ubuntu instance runs inside a container hosted on a virtual machine, systemd-detect-virt prioritizes reporting the innermost container environment. Use command flags to target specific virtualization tiers:
# Query only hardware hypervisors (virtual machines)
systemd-detect-virt --vm
# Query only container environments
systemd-detect-virt --container
If executed inside a Docker container running on a KVM virtual machine, --vm returns kvm, while --container returns docker.
Using systemd-detect-virt in Shell Automation Scripts
Because the utility utilizes standard Linux return codes, administrators can construct clean conditional branching logic in deployment scripts:
#!/bin/bash
# Shell automation script demonstrating environment branching
if systemd-detect-virt --quiet; then
VIRT_TYPE=$(systemd-detect-virt)
echo "Virtualised environment detected: $VIRT_TYPE"
else
echo "Bare-metal physical hardware detected. Initialising physical hardware sensors..."
sudo sensors-detect --auto
fi
The --quiet or -q flag suppresses stdout, ensuring the command outputs nothing while cleanly setting the shell return code ($?) for silent conditional checks.
Conditional Service Execution in systemd Unit Files
Beyond shell scripts, systemd-detect-virt powers native condition checks within systemd service definitions via ConditionVirtualization=:
[Unit]
Description=Hardware Watchdog Daemon
Documentation=man:watchdog(8)
# Only execute if running on physical bare-metal hardware
ConditionVirtualization=false
[Service]
ExecStart=/usr/sbin/watchdog -F
Restart=always
[Install]
WantedBy=multi-user.target
Alternatively, services tailored for virtualized guests (such as QEMU guest agent or Hyper-V KVP daemon) can specify ConditionVirtualization=vm or ConditionVirtualization=kvm to ensure the daemon automatically skips execution if installed on physical hardware.
Auditing Supported Virtualization and Container Identifiers
To view the complete catalog of hypervisor and container technologies recognized by systemd on Ubuntu:
# List all known hypervisors and container engines
systemd-detect-virt --list
The catalog includes modern architectures such as WSL (Windows Subsystem for Linux), bhyve, Parallels, UML (User-Mode Linux), and rkt.