Which CPU, how much RAM, what disk controller and which network driver does this Linux box actually have? The lshw command answers all four in one run, but only when you run it as root. As a normal user it prints a warning and quietly drops entries. On our test VM the tree shrank from 36 lines to 30, and the BIOS entry, the DIMM bank and the whole system disk vanished while the exit code stayed 0.
This guide covers installing lshw on Arch, Debian, Rocky Linux and Fedora, reading its summary views, checking hardware info per class, and parsing its JSON with jq without the error that breaks the obvious filter. Every command below was run in October 2026 on a Debian 13 KVM virtual machine with lshw 02.19, and the Arch Linux, Rocky Linux 10 and Fedora 43 install lines were checked in containers of each distro.
Install lshw on Arch, Debian, Rocky and Fedora
lshw ships in the main repositories of every distro we checked, so you never need a third-party repo or EPEL. It is often missing from minimal and cloud images, though. Our Debian 13 cloud image needed it installed, while the smaller PCI, block and CPU listing tools were already there. The table shows what each package manager installed in our checks.
| Distro | Install command | Package we got | Repository |
|---|---|---|---|
| Arch Linux | sudo pacman -S lshw | B.02.20-3 | extra |
| Debian 13 | sudo apt install lshw | 02.19.git.2021.06.19.996aaad9c7-2.1 | Debian archive |
| Rocky Linux 10 | sudo dnf install lshw | B.02.20-9.el10 | BaseOS |
| Fedora 43 | sudo dnf install lshw | B.02.20-10.fc43 | default repos |
Arch is the one most people search for, and it is the simplest case. lshw sits in the official [extra] repository rather than the AUR, so pacman pulls it directly. Manjaro and EndeavourOS users run the same command, although we only checked stock Arch. On a box you just built with the archinstall script, this is usually one of the first tools worth adding:
sudo pacman -S lshw
On Debian the package comes straight from the distro archive, so apt needs no extra source. Ubuntu uses the same apt command and package name. Our lab only ran it on Debian 13, though.
sudo apt install lshw
Rocky Linux 10 and Fedora 43 both installed it with dnf. On Rocky the package resolves from BaseOS, so there’s nothing to enable first. AlmaLinux and RHEL share the same BaseOS layout, though we did not run them.
sudo dnf install lshw
To confirm the version, lshw -version works on Arch, where it printed B.02.20. The Debian build is different. It prints an empty line and exits 0, which looks like a broken install but isn’t, so ask dpkg instead.
dpkg -l lshw | tail -1
dpkg confirms a 2021 git snapshot that predates upstream B.02.20. An ii in the first column means the package is installed, so the empty -version output is cosmetic.
ii lshw 02.19.git.2021.06.19.996aaad9c7-2.1 amd64 information about hardware configuration
That gap matters little for day-to-day checks, because every command in this guide ran on the older Debian build and worked as shown. If a flag behaves differently on your B.02.20 package, the version difference is the first thing to suspect.
Run lshw with sudo
Always run lshw as root. It reads DMI tables, PCI config space and SCSI devices, and much of that is locked to root. A normal user therefore gets a partial tree, with a generic warning but no hint about what exactly is missing. You will see this the first time you try it without sudo.
lshw -short
Our run’s first lines show the warning, and the tree under it is already wrong. Compare the system line and the memory entries with the root run further down, because that is where you will spot the gaps.
WARNING: you should run this program as super-user.
H/W path Device Class Description
==========================================================
system Computer
/0 bus Motherboard
/0/0 memory 8GiB System memory
/0/1 processor Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
/0/100 bridge 440FX - 82441FX PMC [Natoma]
/0/100/1 bridge 82371SB PIIX3 ISA [Natoma/Triton II]
/0/100/1/0 communication PnP device PNP0501
/0/100/1/1 input PnP device PNP0303
/0/100/1/2 input PnP device PNP0f13
Look at the system line: a normal user gets a generic “Computer” instead of the real product name, which is the first sign the tree is incomplete.
WARNING: you should run this program as super-user.
lshw prints this warning for any user who is not root, followed by a second one saying the output may be incomplete or inaccurate. It decides that from your user ID before it probes anything, so the warning tells you nothing about what actually went missing. Both lines go to stderr and the exit status stays 0:
lshw -short >/dev/null; echo "exit=$?"
A script that discards stderr or only checks the exit code therefore sees a normal run.
WARNING: you should run this program as super-user.
WARNING: output may be incomplete or inaccurate, you should run this program as super-user.
exit=0
To see exactly what a normal user loses, diff the two runs. Lines marked < come from the non-root run and lines marked > from the root run:
diff <(lshw -short 2>/dev/null) <(sudo lshw -short 2>/dev/null)
The gaps are bigger than the 30 versus 36 line count suggests, because whole subtrees are missing rather than single lines.
3c3
< system Computer
---
> system Standard PC (i440FX + PIIX, 1996)
5,6c5,8
< /0/0 memory 8GiB System memory
< /0/1 processor Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
---
> /0/0 memory 96KiB BIOS
> /0/400 processor Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
> /0/1000 memory 8GiB System Memory
> /0/1000/0 memory 8GiB DIMM RAM
22c24,28
< /0/100/5/0 generic Virtual I/O device
---
> /0/100/5/0 scsi0 generic Virtual I/O device
> /0/100/5/0/0.0.0 /dev/sda disk 42GB QEMU HARDDISK
> /0/100/5/0/0.0.0/1 /dev/sda1 volume 39GiB EXT4 volume
> /0/100/5/0/0.0.0/e /dev/sda14 volume 3071KiB BIOS Boot partition
> /0/100/5/0/0.0.0/f /dev/sda15 volume 123MiB Windows FAT volume
Without root, lshw lost the BIOS entry, the DIMM bank under system memory and the entire disk: /dev/sda, its three partitions and the scsi0 name on the controller. The system line fell back to “Computer”, and the CPU sits at /0/1 instead of /0/400, so hardware paths from a non-root run don’t even match a root run. The fix is simply sudo. If you’re writing a script for unprivileged users, don’t parse lshw at all, because it will report a machine with no disk and nothing in the exit code will tell you.
Print a one-screen hardware summary
For a quick hardware check on Linux, -short is the view you’ll use most. It flattens the device tree into four columns: the hardware path, the kernel device name, the class and a description. That’s enough to answer “what’s in this box” in one screen, because it drops every field except the description.
sudo lshw -short
Our Debian 13 VM returned the full tree below. Read it top down, starting with the system and motherboard, then firmware, CPU and memory, then everything hanging off the PCI host bridge at /0/100.

Because this is a KVM guest, every device is virtual, from the QEMU “Standard PC (i440FX + PIIX, 1996)” chassis to the Virtio SCSI controller and Virtio network card. On bare metal (which we did not test for this guide) the same columns carry the real board, NIC and disk models. The Device column is the useful link back to the rest of the system, though lshw may leave it blank, as it did for /dev/sda15 in this capture. Names like /dev/sda and eth0 are the ones you’ll pass to smartctl, ip or fdisk. One oddity is worth knowing: the “123MiB Windows FAT volume” is not Windows. It is the EFI system partition, which is FAT formatted, and lshw labels it by filesystem type.
When you need PCI addresses instead of tree paths, for passthrough or for matching a device to lspci, switch to the bus view:
sudo lshw -businfo
The bus info column now shows addresses such as pci@0000:00:12.0 for the network card and scsi@0:0.0.0 for the disk. Those are the addresses you match against lspci when you hand a device to a VM, because passthrough configs name the PCI address rather than the interface. Tree paths, by contrast, only mean something to lshw itself.
Bus info Device Class Description
========================================================
system Standard PC (i440FX + PIIX, 1996)
bus Motherboard
memory 96KiB BIOS
cpu@0 processor Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
memory 8GiB System Memory
memory 8GiB DIMM RAM
pci@0000:00:00.0 bridge 440FX - 82441FX PMC [Natoma]
pci@0000:00:01.0 bridge 82371SB PIIX3 ISA [Natoma/Triton II]
communication PnP device PNP0501
input PnP device PNP0303
input PnP device PNP0f13
storage PnP device PNP0700
system PnP device PNP0b00
pci@0000:00:01.1 scsi2 storage 82371SB PIIX3 IDE [Natoma/Triton II]
scsi@2:0.0.0 /dev/cdrom disk QEMU DVD-ROM
/dev/cdrom disk
pci@0000:00:01.2 bus 82371SB PIIX3 USB [Natoma/Triton II]
pci@0000:00:01.3 bridge 82371AB/EB/MB PIIX4 ACPI
pci@0000:00:03.0 generic Virtio memory balloon
virtio@0 generic Virtual I/O device
pci@0000:00:05.0 storage Virtio SCSI
virtio@1 scsi0 generic Virtual I/O device
scsi@0:0.0.0 /dev/sda disk 42GB QEMU HARDDISK
scsi@0:0.0.0,1 /dev/sda1 volume 39GiB EXT4 volume
scsi@0:0.0.0,14 /dev/sda14 volume 3071KiB BIOS Boot partition
scsi@0:0.0.0,15 volume 123MiB Windows FAT volume
pci@0000:00:08.0 communication Virtio console
virtio@2 generic Virtual I/O device
pci@0000:00:12.0 network Virtio network device
virtio@3 eth0 network Ethernet interface
pci@0000:00:1e.0 bridge QEMU PCI-PCI bridge
pci@0000:00:1f.0 bridge QEMU PCI-PCI bridge
input0 input AT Translated Set 2 keyboard
input2 input Power Button
Lines with an empty bus column are devices lshw did not find on a PCI, SCSI or virtio bus, such as memory read from the DMI tables and the legacy PnP devices. That’s normal and not a sign of a missing driver, so don’t chase it.
Check CPU, memory, network and disk by class
The -class option narrows lshw to one device type and prints every field it knows, which is where the detail lives that -short hides. The class names come straight from the Class column, and our VM’s tree used these:
- system, bus and bridge
- processor and memory
- storage, disk and volume
- network and communication
- input and generic
Most hardware questions come down to processor, memory, network or disk, so those are the four worth knowing by heart. The others are mostly plumbing.
CPU details
The processor class gives you the model, core and thread counts, microcode level and every CPU flag the kernel sees. That is how you confirm AES or virtualization support before installing software that depends on it.
sudo lshw -class processor
Check the configuration line for core counts and the capabilities line for flags. You will come back to those two lines whenever an installer complains that the CPU lacks a feature, so it pays to know where they sit.
*-cpu
description: CPU
product: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
vendor: Intel Corp.
physical id: 400
bus info: cpu@0
version: 6.94.3
slot: CPU 0
size: 2GHz
capacity: 2GHz
width: 64 bits
capabilities: fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp x86-64 constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 xsaves arat vnmi umip md_clear flush_l1d arch_capabilities
configuration: cores=4 enabledcores=4 microcode=226 threads=4
Don’t trust the size: 2GHz line inside a VM. The i7-6700 is a 3.40GHz part, and inxi reported 3408 MHz on the same guest. lshw instead reads the speed from the SMBIOS table that QEMU generates, and QEMU fills in 2GHz. The hypervisor flag in the capabilities list is the giveaway that you’re inside a guest. The vmx flag next to it means nested virtualization is exposed, which you’d want before running KVM inside this VM. For clock speeds and cache sizes, use lscpu or a tool like cpufetch for a CPU summary.
Memory and firmware
The memory class covers more than RAM. It also lists the firmware, because lshw treats the BIOS ROM as a memory device. One command therefore tells you the BIOS vendor and date as well as how many DIMM slots are populated.
sudo lshw -class memory
Our guest has one 8GiB bank behind SeaBIOS, and ECC is reported as multi-bit. The firmware block comes first, so you get the BIOS version without a second command.
*-firmware
description: BIOS
vendor: SeaBIOS
physical id: 0
version: rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org
date: 04/01/2014
size: 96KiB
*-memory
description: System Memory
physical id: 1000
size: 8GiB
capabilities: ecc
configuration: errordetection=multi-bit-ecc
*-bank
description: DIMM RAM
vendor: QEMU
physical id: 0
slot: DIMM 0
size: 8GiB
On a physical server each *-bank entry maps to a DIMM slot, which is how you plan an upgrade without opening the case. Treat the ECC line on a VM with suspicion, since it describes what QEMU advertises rather than the host’s modules. If you’re shopping for real ECC RAM for a homelab, check the bank entries on the host itself.
Network card and driver
The network class is the quickest way to map an interface name to the driver bound to it. You need that when a NIC isn’t coming up, or when you want to confirm which driver the kernel picked.
sudo lshw -class network
Here the parent entry is the PCI device and the child is the interface, so read the child for the logical name and the driver= field in its configuration line.
*-network
description: Ethernet controller
product: Virtio network device
vendor: Red Hat, Inc.
physical id: 12
bus info: pci@0000:00:12.0
version: 00
width: 64 bits
clock: 33MHz
capabilities: msix bus_master cap_list rom
configuration: driver=virtio-pci latency=0
resources: iomemory:700-6ff irq:10 ioport:e0e0(size=32) memory:fea42000-fea42fff memory:706000c000-706000ffff memory:fea00000-fea3ffff
*-virtio3
description: Ethernet interface
physical id: 0
bus info: virtio@3
logical name: eth0
serial: 52:54:00:12:34:56
capabilities: ethernet physical
configuration: autonegotiation=off broadcast=yes driver=virtio_net driverversion=1.0.0 ip=10.0.1.50 link=yes multicast=yes
A card with no driver= entry in its configuration line has no kernel driver bound. That is the first thing to fix, before you touch any network config. Note that the serial field is the MAC address and the configuration line carries the IP, which matters as soon as you share this output with anyone.
Disks and partitions
You can pass -class more than once, and lshw shows the union. Combining disk and volume with -short gives a compact storage map that includes the CD drive and every partition.
sudo lshw -class disk -class volume -short
Each partition sits under its disk with its size and filesystem type, so you can see the layout without opening fdisk. The last part of each path is the partition number in hex. That is why /dev/sda14 sits at /e and the 15th partition at /f.
H/W path Device Class Description
==========================================================
/0/100/1.1/0.0.0 /dev/cdrom disk QEMU DVD-ROM
/0/100/1.1/0.0.0/0 /dev/cdrom disk
/0/100/5/0/0.0.0 /dev/sda disk 42GB QEMU HARDDISK
/0/100/5/0/0.0.0/1 /dev/sda1 volume 39GiB EXT4 volume
/0/100/5/0/0.0.0/e /dev/sda14 volume 3071KiB BIOS Boot partition
/0/100/5/0/0.0.0/f volume 123MiB Windows FAT volume
lshw reports the disk as 42GB (decimal) while lsblk on the same box says 40G (binary), so don’t be surprised when the two tools disagree on size. For usage rather than layout, one of the disk partition and usage viewers is a better fit than lshw.
Sanitize the output before sharing it
Add -sanitize whenever lshw output is headed for a forum post, a vendor ticket or a chat. As the network section showed, the default output includes MAC addresses, IP addresses and serial numbers, and on physical hardware the serials of your board and disks too. The flag replaces those values with [REMOVED] and leaves everything else intact:
sudo lshw -class network -sanitize | grep -E "serial|ip="
Both the MAC and the IP are replaced, while the driver and link fields you need for troubleshooting stay readable.
serial: [REMOVED]
configuration: autonegotiation=off broadcast=yes driver=virtio_net driverversion=1.0.0 ip=[REMOVED] link=yes multicast=yes
We only checked the network fields shown here, so read the rest of the output once before posting it. Make the flag a habit on anything that leaves the machine.
Export lshw output as JSON, HTML or XML
lshw writes three machine formats: -json for scripts, -xml for older tooling, and -html for a report you can open in a browser. Add -quiet to each one, because without it lshw prints a progress line on the terminal while it scans. The HTML and XML reports are easy to produce:
sudo lshw -html -quiet > /tmp/hw.html; sudo lshw -xml -quiet > /tmp/hw.xml; ls -lh /tmp/hw.html /tmp/hw.xml
On our VM the HTML report came to 49K and the XML to 33K, small enough to attach to any ticket.
-rw-rw-r-- 1 josphat josphat 49K Oct 20 11:47 /tmp/hw.html
-rw-rw-r-- 1 josphat josphat 33K Oct 20 11:47 /tmp/hw.xml
The XML header also records the kernel and glibc the report was taken on. That is handy when you collect inventory from many hosts and later need to know which kernel saw which hardware. The HTML version is the one to attach to a ticket for someone who does not live in a terminal.
JSON is where most people go next, because it is the only format a script can query without screen-scraping. One class is enough to see the shape of it:
sudo lshw -json -class processor | head -20
Numeric fields such as size are raw integers in hertz or bytes here, not the rounded “2GHz” from the text view, so you do any unit conversion yourself in jq. Add -quiet when a script captures this output, as the later examples do, so the scan progress line never ends up in your logs.
[
{
"id" : "cpu",
"class" : "processor",
"claimed" : true,
"handle" : "DMI:0400",
"description" : "CPU",
"product" : "Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz",
"vendor" : "Intel Corp.",
"physid" : "400",
"businfo" : "cpu@0",
"version" : "6.94.3",
"slot" : "CPU 0",
"units" : "Hz",
"size" : 2000000000,
"capacity" : 2000000000,
"width" : 64,
"configuration" : {
"cores" : "4",
"enabledcores" : "4",
Notice the leading [. That’s the first of two traps that break jq filters copied from elsewhere, and both come from lshw’s JSON shape rather than from jq. So a filter you copied from a guide that queried the full tree needs a .[] in front before it works on a class.
bash: jq: command not found
Our Debian 13 cloud image did not ship jq, so the first pipe into it failed with exit code 127. Install it from the distro repository. Debian 13 installed package 1.7.1-6+deb13u4, whose binary reports itself as jq-1.7.
sudo apt install jq
Once jq --version prints a version, the pipes below work. The two problems that follow are not install issues: they come from how lshw shapes its JSON.
Array vs object: why your jq filter returns nothing
With -class, lshw returns a JSON array of matching devices. Without it, you get a single object for the whole machine, with children nested inside. A filter written for one silently fails on the other, and you can check which one you have with jq’s type:
sudo lshw -json -class processor -quiet | jq type; sudo lshw -json -quiet | jq type
jq reports an array for the filtered call and an object for the full tree, which is why the same filter can work in one pipe and print nothing in the other.
"array"
"object"
So start class-filtered queries with .[], and use .. to walk the full tree. Getting total RAM in GiB from the memory class works like this.
sudo lshw -json -class memory -quiet | jq -r '.[] | select(.id=="memory") | .size/1073741824 | tostring + " GiB"'
It returns the same 8 GiB the text view showed.
8 GiB
The select(.id=="memory") step matters because the memory class also returns the firmware entry. Without it, dividing that 96KiB by a GiB would print a near-zero line next to your real total. Filter on id rather than array position, so the query keeps working on a machine that lists its entries in a different order.
jq: error: array is not valid in a csv row
The second trap hit us when we tried to list disks as tab-separated rows by walking the full tree.
sudo lshw -json -quiet | jq -r '.. | objects | select(.class=="disk" and .logicalname!=null) | [.logicalname, .product, .size] | @tsv'
jq stopped at the CD drive with this error, and on our box it printed no rows before failing.
jq: error (at <stdin>:700): array (["/dev/cdro...) is not valid in a csv row
lshw does not give logicalname a fixed type. It is a plain string for most devices but an array when a device has several names, and the CD drive had two:
sudo lshw -json -quiet -class disk | jq -c '.[] | {product, logicalname}'
Only the first entry is an array, and that is what broke @tsv. The other two are plain strings, which is why the filter looked fine until it reached the CD drive. A filter tested on a machine with only plain disks gives you no hint of the problem.
{"product":"QEMU DVD-ROM","logicalname":["/dev/cdrom","/dev/sr0"]}
{"product":null,"logicalname":"/dev/cdrom"}
{"product":"QEMU HARDDISK","logicalname":"/dev/sda"}
Normalize the field before building the row. Take the first element when it is an array, and default a missing size to 0 so the row never has a null in it. This version ran clean on the same box.
sudo lshw -json -quiet -class disk | jq -r '.[] | [(.logicalname | if type=="array" then .[0] else . end), .product, (.size // 0 | tostring)] | @tsv'
Each disk now prints one row with the size in bytes, and the second /dev/cdrom line is the empty child entry that -short also showed.
/dev/cdrom QEMU DVD-ROM 0
/dev/cdrom 0
/dev/sda QEMU HARDDISK 42949672960
Apply the same guard to any field you feed into @tsv or @csv. Fields that look like strings on one machine can turn into arrays on the next, and an inventory script that works on one machine fails on the next device that carries a second name.
Trim the scan for scripts
lshw is fast enough for interactive use, and you can make it faster by switching off probes you don’t need with -disable. That’s worth doing in a cron job or an inventory agent that runs across a fleet. We timed the full scan against one with DMI and SCSI probing turned off:
time sudo lshw -short -quiet >/dev/null; time sudo lshw -short -quiet -disable dmi -disable scsi >/dev/null
Dropping the two probes cut the run from 0.186 to 0.107 seconds, about 43 percent in a single run.
real 0m0.186s
user 0m0.066s
sys 0m0.042s
real 0m0.107s
user 0m0.076s
sys 0m0.028s
Both numbers are tiny because a VM has few devices. We only measured this guest, so time it on your own hosts before deciding the saving is worth it. The cost is real, though: disabling DMI throws away exactly the memory bank and firmware detail that the root run exists for. We’d only disable a probe when the script never reads that class.
lshw vs dmidecode vs inxi
lshw is the best single command when you want the whole device tree with drivers and bus addresses. It is not the only option, though, and on our Debian 13 VM neither dmidecode nor inxi was installed by default. The table compares them on the same box, with the two preinstalled helpers alongside:
| Tool | On the Debian 13 cloud image | Best for | Root needed | Machine output |
|---|---|---|---|---|
| lshw | No, apt install | Full device tree, drivers, bus addresses | Yes, or entries go missing | JSON, XML, HTML |
| dmidecode | No, apt install | Firmware tables: DIMM slots, serials, board | Yes | No |
| inxi | No, apt install | Readable summary, CPU clock, RAM in use | No for -m; serials need root | JSON/XML via --output (add --tty in scripts) |
| lscpu, lsblk | Yes | CPU topology, block devices | No | JSON with -J |
dmidecode reads the same SMBIOS tables lshw does, so on this VM it agreed with lshw on the memory and the system product name. Its output is narrower but closer to the source, which is why it’s the one to use for slot-level detail. Our dmidecode guide covers its type numbers:
sudo dmidecode -t memory | grep -E "Size|Type:|Speed|Manufacturer" | head -6; sudo dmidecode -s system-product-name
On a VM the speed fields stay unknown because QEMU does not fill them in, which matches what lshw showed for the same bank.
Error Correction Type: Multi-bit ECC
Size: 8 GB
Type: RAM
Speed: Unknown
Manufacturer: QEMU
Configured Memory Speed: Unknown
Standard PC (i440FX + PIIX, 1996)
inxi takes the opposite approach and aims for a readable summary. It got the CPU clock right where lshw did not (3408 MHz rather than 2GHz), and it showed RAM in use without sudo. Use -c0 whenever inxi runs without a terminal on stdin (cron, scripts, Ansible or ssh host 'inxi ...'). In that case it keeps its colour codes and they show up as junk like 12System, while an interactive run that pipes into another command switches colours off on its own. The -z flag filters MAC addresses:
inxi -c0 -Cmz
Memory use and per-core clocks come back on a few clean lines.
Memory:
System RAM: total: 8 GiB available: 7.76 GiB used: 1.09 GiB (14.1%)
Array-1: capacity: 8 GiB slots: 1 modules: 1 EC: Multi-bit ECC
Device-1: DIMM 0 type: RAM size: 8 GiB speed: N/A
CPU:
Info: quad core model: Intel Core i7-6700 bits: 64 type: MCP cache: L2: 16 MiB
Speed (MHz): avg: 3408 min/max: N/A cores: 1: 3408 2: 3408 3: 3408 4: 3408
inxi can also emit JSON, and from an interactive terminal the plain --output json form works even when you pipe it. Run without a terminal on stdin, as in a script or a non-interactive SSH command, it failed on our VM with “Error 1: You can’t run option help in an IRC client!”. With no terminal, inxi assumes it is running inside a chat client. Forcing terminal mode with --tty, together with -c0, fixes it for non-interactive runs:
inxi --tty -c0 -m --output json --output-file print
The JSON works, but every key carries inxi’s internal sort prefix ("001#1#2#total"), so it is harder to query than lshw’s output. That is one more reason to keep lshw for scripts.
Before installing inxi on a lean server, know that apt pulls in its Recommends by default, and those include dmidecode, bind9-dnsutils and file. Our inxi -F run even reported an llvmpipe OpenGL renderer on this headless VM, although the lab VM also had libvirt installed, so we can’t say which package brought the graphics stack in. We did not test --no-install-recommends, so check what it leaves out if you try it. For the CPU alone, lscpu is already installed and gives the topology without any of that:
lscpu | head -14
The output confirms four CPUs, one thread per core and one socket.
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 39 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Vendor ID: GenuineIntel
Model name: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
CPU family: 6
Model: 94
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 1
Stepping: 3
Pick the tool by the question you’re asking:
- Full inventory, drivers or JSON for a script: lshw with sudo
- DIMM slots, serial numbers or board model: dmidecode
- Quick readable summary or real CPU clock in a VM: inxi with
-c0 - CPU topology or disk layout on a box you can’t install on: lscpu and lsblk
Our own default is lshw for anything that ends up in a ticket or an inventory file, run with -sanitize, and inxi when we just want to eyeball a machine. Neither lshw nor dmidecode reports temperatures or fan speeds, so for health rather than inventory, set up hardware health monitoring alongside them. Upstream source and the full option list are in the lshw project on GitHub.