Optimized way to grab CPU, GPU(nouveau) temperature and fan info for bash scripts

In this article, I propose a method that I use myself. Probably it is not ideal, but it allows you to avoid unnecessary applications using only kernel information from RAM. In any case, I hope it will be interesting.

First, we need to figure out which kernel modules need to be loaded in order to collect hardware information. Install lm-sensors package, it allows you to analyze and get information in a beautiful way. In any case, it will help us, you will see it later.

sudo apt install lm-sensors

Then run this command. It’s safe.

sudo sensors-detect

Answer “Yes” if possible so that the analysis is deeper.

The last question will be

To load everything that is needed, add this to /etc/modules:
#----cut here----
# Chip drivers
#----cut here----
Do you want to add these lines automatically to /etc/modules? (yes/NO)

So, if you answer Yes, then all the necessary kernel modules will be loaded automatically at system startup.

Two modules were found on my system


As the name implies, one for the CPU and the other for the motherboard. So you can collect information about the temperature of the CPU, motherboard and fan speeds.

You can now reboot your system, or load the modules you have listed manually. To load your kernel modules manually use modprobe

sudo modprobe coretemp
sudo modprobe it87

To make sure the module is already running use

cat /proc/modules | grep coretemp
coretemp 16384 0 - Live 0x0000000000000000

You can now view all available sensors by the command

Adapter: PCI adapter
GPU core:     +0.94 V  (min =  +0.93 V, max =  +1.11 V)
fan1:        3990 RPM
temp1:        +53.0°C  (high = +95.0°C, hyst =  +3.0°C)
                       (crit = +105.0°C, hyst =  +5.0°C)
                       (emerg = +135.0°C, hyst =  +5.0°C)
Adapter: ISA adapter
Core 0:       +57.0°C  (high = +80.0°C, crit = +100.0°C)
Core 1:       +47.0°C  (high = +80.0°C, crit = +100.0°C)
Core 2:       +55.0°C  (high = +80.0°C, crit = +100.0°C)
Core 3:       +55.0°C  (high = +80.0°C, crit = +100.0°C)
fan1:        1713 RPM  (min =    0 RPM)
fan2:           0 RPM  (min =    0 RPM)
fan3:           0 RPM  (min =    0 RPM)
temp1:        +47.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp2:        +32.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermal diode

As you can see here the information about the GPU provided by nouveau driver, the information about CPU temperature provided by coretemp kernel module and the information about my motherboard provided by it87 kernel module. The it87 module clearly shows there are 3 fans on my motherboard. I turned off two of them, and one works on the processor radiator.

That’s cool, this is a quick way to get information. But what if we want to get it directly from the kernel module? You are half a step away from it.

Journey to the /sys/ to get sensors information directly

If you loaded kernel modules as described above, you can now receive information for your scripts and programs directly. Without grep, sed, awk or something else.

Run this command. It will find all the directories of monitoring sensors.

sudo find /sys/ -name hwmon

See these familiar kernel module names? And my GPU is connected to the PCI bus.

/sys/class/hwmon just contains symlinks to these directories.

ls -l /sys/class/hwmon/
hwmon0 -> ../../devices/platform/coretemp.0/hwmon/hwmon0
hwmon1 -> ../../devices/platform/it87.656/hwmon/hwmon1
hwmon2 -> ../../devices/pci0000:00/0000:00:01.0/0000:01:00.0/hwmon/hwmon2

Let’s take an example of how this works

Let it be a processor, for example.

Remember the output of the sensor utility?

Adapter: ISA adapter
Core 0:       +57.0°C  (high = +80.0°C, crit = +100.0°C)
Core 1:       +47.0°C  (high = +80.0°C, crit = +100.0°C)
Core 2:       +55.0°C  (high = +80.0°C, crit = +100.0°C)
Core 3:       +55.0°C  (high = +80.0°C, crit = +100.0°C)

As you can see, there is information for each core, including critical values. Let’s compare it with the files in the corresponding kernel module directory.

ls /sys/devices/platform/coretemp.0/hwmon/hwmon0/
device      temp2_crit_alarm  temp3_crit_alarm  temp4_crit_alarm  temp5_crit_alarm
name        temp2_input       temp3_input       temp4_input       temp5_input
power       temp2_label       temp3_label       temp4_label       temp5_label
subsystem   temp2_max         temp3_max         temp4_max         temp5_max
temp2_crit  temp3_crit        temp4_crit        temp5_crit        uevent

But here the files for each core are numbered like 2, 3, 4, 5.

Let’s open one file, let it be temp2_input, the first CPU core

cat /sys/devices/platform/coretemp.0/hwmon/hwmon0/temp2_input

This is the temperature value for the first core. But it means 58 degrees Celsius. Probably the value can’t be floating point, so it was made integer, for compatibility. The last three zeros can serve as a decimal point if the sensor on the processor supports it, I think so.

You can divide it by 1000 and write to variable in bash, this way your scripts can receive this information directly.

CPU_T=$(< /sys/devices/platform/coretemp.0/hwmon/hwmon0/temp2_input)
CPU_T=$(expr "$CPU_T" / 1000)

cat utility is not used here, so it is pure bash.

You can also write it to a file.

echo "$CPU_T" >> /tmp/CpuTemperature.sensors

Then read it like in the way above

VALUE_FOR_MY_SCRIPT=$(< /tmp/CpuTemperature.sensors)

If your /tmp/ directory is mounted as tmpfs, then all operations will be produced in RAM.

This is how it works.

Don’t forget to compare the file names in the directories of the sensor modules WITH sensors utility output. This will help you figure it out!

Get fan speed from gpu and motherboard

I have fans on the motherboard (including the processor) and on the video adapter. In this case, you can find their speed by same file name.

GPU fan speed:

cat /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/hwmon/hwmon2/fan1_input

This value means rounds per minute.

And i have 3 fans on my motherboard:

ls /sys/devices/platform/it87.656/hwmon/hwmon1 | grep "fan[1,2,3]_input"

The rotation speed can be found as above.

Now, that’s all.