Programatically determine if an script is being executed on laptop or desktop?
Is there any reliable way to determine (programmatically) from within a bash script if it is being executed on a laptop or a desktop computer?
I could obviously just prompt the user to ask them, but that is pretty clunky.
Solution 1:
Looking at whether or not the system has a battery is not reliable - a UPS connected to the system (not just for power, but over USB as well for automatic shutdown and battery monitoring) may show up as a battery.
There is a nice reliable way however:
dmidecode --string chassis-type
On a laptop, this will return one of "Laptop", "Notebook" "Portable", or "Sub Notebook" (depending on what the manufacturer coded into the BIOS). There is a full list of possible values at "Identifying the Chassis Type of a Computer" in the Windows 2000 Scripting Guide - don't worry about it being a Microsoft TechNet page, this is not OS specific.
dmidecode can also get information about the hardware manufacturer, system serial number (sometimes), etc.
Solution 2:
To avoid using sudo, you can read the contents of /sys/class/dmi/id/chassis_type
, which will return the decimal value of the chassis type.
The meaning of the values can be seen in official documentation PDFs available at https://www.dmtf.org/standards/SMBIOS
The following table includes the information for smbios specification version 3.5.0 (22 Sep 2021).
Decimal value | Hex value | Meaning |
---|---|---|
1 | 01h | Other |
2 | 02h | Unknown |
3 | 03h | Desktop |
4 | 04h | Low Profile Desktop |
5 | 05h | Pizza Box |
6 | 06h | Mini Tower |
7 | 07h | Tower |
8 | 08h | Portable |
9 | 09h | Laptop |
10 | 0Ah | Notebook |
11 | 0Bh | Hand Held |
12 | 0Ch | Docking Station |
13 | 0Dh | All in One |
14 | 0Eh | Sub Notebook |
15 | 0Fh | Space-saving |
16 | 10h | Lunch Box |
17 | 11h | Main Server Chassis |
18 | 12h | Expansion Chassis |
19 | 13h | SubChassis |
20 | 14h | Bus Expansion Chassis |
21 | 15h | Peripheral Chassis |
22 | 16h | RAID Chassis |
23 | 17h | Rack Mount Chassis |
24 | 18h | Sealed-case PC |
25 | 19h | Multi-system chassis When this value is specified by an SMBIOS implementation, the physical chassis associated with this structure supports multiple, independently reporting physical systems—regardless of the chassis' current configuration. Systems in the same physical chassis are required to report the same value in this structure's Serial Number field. For a chassis that may also be configured as either a single system or multiple physical systems, the multi-system chassis value is reported even if the chassis is currently configured as a single system. This allows management applications to recognize the multi-system potential of the chassis. |
26 | 1Ah | Compact PCI |
27 | 1Bh | Advanced TCA |
28 | 1Ch | Blade An SMBIOS implementation for a Blade would contain a Type 3 Chassis structure for the individual Blade system as well as one for the Blade Enclosure that completes the Blade system. |
29 | 1Dh | Blade Enclosure A Blade Enclosure is a specialized chassis that contains a set of Blades. It provides much of the non-core Computing infrastructure for a set of Blades (power, cooling, networking, and so on). A Blade Enclosure may itself reside inside a Rack or be a standalone chassis. |
30 | 1Eh | Tablet |
31 | 1Fh | Convertible |
32 | 20h | Detachable |
33 | 21h | IoT Gateway |
34 | 22h | Embedded PC |
35 | 23h | Mini PC |
36 | 24h | Stick PC |
Solution 3:
Debian Solution:
To find whether a machine running Debian is a laptop, try:
[ -d /sys/module/battery ] && echo "Yes it's a laptop"
This approach does not require root
privileges.
On other distributions, however, this directory seems to exist, at least in skeleton form, regardless of whether or not there is a battery. From the comments (below), these distributions include CentOS, Ubuntu, and the Ubuntu-derived distribution of Linux Mint.
More General Solution
Although it does not work on my Debian systems, the solution proposed by Alex reportedly works on Ubuntu & CentOS. Thus suggests, for greater generality, a possible combined solution:
[ -f /sys/module/battery/initstate ] || [ -d /proc/acpi/battery/BAT0 ] && echo "Yes it's a laptop"
This approach does not require root
privileges.
More Details
On a Debian system with an actual battery, the /sys/module/battery
directory contains many files. One such file is /sys/module/battery/initstate
which contains the text live
. On Ubuntu, however, these files do not exist even on actual laptops. Thus, it appears that the presence of the file /sys/module/battery/initstate
can be used to test for a laptop running Debian.
On Debian systems that I tested, by contrast, the /proc/acpi/battery
directory did not exist.