<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Scripting on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/scripting/</link><description>Recent content in Scripting on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Thu, 27 Apr 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/scripting/index.xml" rel="self" type="application/rss+xml"/><item><title>Linux Shell Script for Temperature Logging</title><link>https://blog.iankulin.com/linux-shell-script-for-temperature-logging/</link><pubDate>Thu, 27 Apr 2023 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/linux-shell-script-for-temperature-logging/</guid><description>&lt;p&gt;A potential solution to my concern about the either perfect, or nearly dead, SSD would be to add a NVMe disk to the M.2 slot in the HP Elitedesk 800 G2&amp;rsquo;s. I&amp;rsquo;d use those to boot from and run Proxmox, then the existing SSD&amp;rsquo;s on each node in the cluster would just be part of the CephFS pool that has some redundancy built into it and hosts the VMs that are not using the NAS for their storage.&lt;/p&gt;
&lt;p&gt;These &amp;lsquo;gumstick&amp;rsquo; NVMe drives are remarkably good value in the smaller sizes at the moment, with Samsung 250GB NVMe&amp;rsquo;s costing less than a pack of cigarettes in Australia.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-04-20-at-7.02.57-pm.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;A small concern I&amp;rsquo;ve got about that, and about the (very cute looking) way I&amp;rsquo;ve just got the computers all stacked on top of each other, is about the internal temperatures. I noticed SSD temperatures in the SMART data I was looking the other day, and I&amp;rsquo;ve seen CPU temperatures somewhere, so this data is available. So I set out on a quest to log some of it so I could do a before and after (NMVe installation) look at the temperatures.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.pyroelectro.com/tutorials/cron-automation/check.html"&gt;This article&lt;/a&gt; was very close to what I wanted - a shell script to run in a cron job that would log the drive and CPU temperatures. The script goes a fair way beyond that, but my main issue was that it uses a couple of packages - &lt;code&gt;sensors&lt;/code&gt;, and &lt;code&gt;hddtemp&lt;/code&gt;. I like to avoid dependencies if I can, but I also thought the temp data was pretty simple and is probably just sitting in the &lt;code&gt;/sys/&lt;/code&gt; directory tree somewhere.&lt;/p&gt;
&lt;p&gt;That sort of turned out to be true. In /sys/class/hwmon/ there&amp;rsquo;s a couple of directories (actually symlinks) for bits of hardware that can be monitored for temperature, and in those directories are text files with some values, the ones we&amp;rsquo;re interested in being &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;temp1_input&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root@pve-dev1:~# tree /sys/class/hwmon/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/sys/class/hwmon/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── hwmon0 -&amp;gt; ../../devices/virtual/thermal/thermal_zone0/hwmon0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── hwmon1 -&amp;gt; ../../devices/platform/coretemp.0/hwmon/hwmon1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└── hwmon2 -&amp;gt; ../../devices/pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0/hwmon/hwmon2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;3 directories, 0 files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root@pve-dev1:~# ls /sys/class/hwmon/hwmon0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;device name power subsystem temp1_input uevent
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root@pve-dev1:~# cat /sys/class/hwmon/hwmon0/name /sys/class/hwmon/hwmon0/temp1_input
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pch_skylake
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;45500
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://commons.wikimedia.org/w/index.php?curid=9817206"&gt;&lt;img src="https://blog.iankulin.com/images/intel_5_series_architecture.png" width="232" alt=""&gt;&lt;/a&gt;
&lt;em&gt;Intel 5 architecture - Anas hashmi&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The first two are temperatures of the &lt;a href="https://commons.wikimedia.org/w/index.php?curid=9817206"&gt;Platform Controller Hub (PCH)&lt;/a&gt; and actual CPU. Both of these values were already just sitting there.&lt;/p&gt;
&lt;p&gt;The third value, for the SSD temperature didn&amp;rsquo;t appear until added by running &lt;code&gt;modprobe drivetemp&lt;/code&gt; to load a kernel module.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the three values I want to log sorted then, but how to go about it? &lt;a href="http://www.pyroelectro.com/tutorials/cron-automation/check.html"&gt;That first article&lt;/a&gt; I mentioned had a shell script using printf() to output some values to a log file, then the script was triggered by a cron job. Two things I&amp;rsquo;ve never done before, so let&amp;rsquo;s dive in. Here&amp;rsquo;s the finished code.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-04-20-at-8.32.11-pm.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;I wrote MS-DOS batch files in the 1980s so this wasn&amp;rsquo;t completely alien to me. A few points were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Everyone else&amp;rsquo;s shell scripts start with &lt;code&gt;#!/bin/bash&lt;/code&gt; so I assume that&amp;rsquo;s compulsory. Other lines starting with &lt;code&gt;#&lt;/code&gt; are comments.&lt;/li&gt;
&lt;li&gt;In that list of variables, each one is filled with the results of the command being assigned to it in the single quotes. So if typing in &lt;code&gt;cat /sys/class/hwmon/hwmon0/name&lt;/code&gt; at the terminal prompt would result in the output &lt;code&gt;pch_skylake&lt;/code&gt;, then the variable &lt;code&gt;pch_name&lt;/code&gt; will contain &lt;code&gt;pch_skylake&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re not coming to this from a programming background, this printf() command is going to look weird.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;printf &amp;#34;$(date +&amp;#39;%d/%m/%Y,%T&amp;#39;),%s,%d,%s,%d,%s,%d\n&amp;#34; $pch_name $pch_temp $cpu_name $cpu_temp $ssd_name $ssd_temp &amp;gt;&amp;gt; $log_file
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;How these work is that the first part is the string to print, but it has some placeholders (all those &lt;code&gt;%&lt;/code&gt;letters). At runtime, the values from the end of the line are inserted into them. Like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root@pve-dev1:~# printf &amp;#34;Hello %s\n&amp;#34; &amp;#34;Ian&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Hello Ian
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;%s&lt;/code&gt; is a placeholder for a some text, then we supply the text at the end - &lt;code&gt;&amp;quot;Ian&amp;quot;&lt;/code&gt;. In this case, &lt;code&gt;&amp;quot;Ian&amp;quot;&lt;/code&gt; is a string literal, if we&amp;rsquo;d used a variable (as in our logging script) then the contents of the variable would be used instead. The &lt;code&gt;\n&lt;/code&gt; at the end of the string is a newline character so whatever comes after starts on a new line.&lt;/p&gt;
&lt;p&gt;At this point I know enough about Linux permissions that I knew I&amp;rsquo;d have to set the shell script file to be executable with a &lt;code&gt;chmod 755&lt;/code&gt;, and to call it with the &lt;code&gt;./&lt;/code&gt; in front of it that I was perplexed about a couple of days ago.&lt;/p&gt;
&lt;p&gt;Again, the original article gave an example of the line to put into /etc/crontab. It just needed the path to my script and it was good to go.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# Example of job definition:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# .---------------- minute (0 - 59)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# | .------------- hour (0 - 23)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# | | .---------- day of month (1 - 31)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# | | | | |
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# * * * * * user-name command to be executed
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;*/5 * * * * root /root/bin/tempCheck.sh 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next thing you know, the log file is slowly growing at &lt;code&gt;/var/log/temps.csv&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,20:30:01,pch_skylake,45000,coretemp,38000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,20:35:01,pch_skylake,45000,coretemp,37000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,20:40:01,pch_skylake,44500,coretemp,37000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,20:45:01,pch_skylake,45000,coretemp,37000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,20:50:01,pch_skylake,44500,coretemp,37000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,20:55:01,pch_skylake,44500,coretemp,37000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,21:00:01,pch_skylake,45000,coretemp,37000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,21:05:01,pch_skylake,45500,coretemp,38000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,21:10:01,pch_skylake,45000,coretemp,38000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20/04/2023,21:15:01,pch_skylake,45500,coretemp,37000,drivetemp,38000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Obviously I&amp;rsquo;m going to graph this, and also obviously, I&amp;rsquo;m going to run a CPU stress test in a VM in the middle of the data collection.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/temp-chart.jpg" alt=""&gt;&lt;/p&gt;</description></item></channel></rss>