For me, the hardest part about teaching the LPI 101 course is teaching about text-stream filters. It’s not that they’re difficult to understand. It’s just that showing the examples of how they work is easy, but showing examples of how they can be used in real life is a bit more challenging. Real-life examples from the Linux admin world are fairly complex, and are beyond the level that most beginning Linux students are able to grasp. So, in most LPI books, the student will see how these utilities work, but not how to use them.
Text-stream filters can be used as stand-alone tools, if you have occasion to use them in that manner. But, you can also use them in scripts to solve problems, whether you’re a Linux admin or just a home user. Here’s an example of how I used text-stream filters to solve a long-standing problem on one of my home computers. (In fact, it’s the computer that I’m using to type this.)
This particular computer has a problem with CPU-overheating. If I try to run it at its full rated speed of 2.7 GHz with a room temperature above about 70 degrees or so Fahrenheit, the CPU temperature will soon climb up to 212 degrees, which will cause the computer to shut down. It’s a strange problem, considering that the CPU is only rated for a 65-watt power draw, and that I’ve installed a full tower CPU cooler and extra fans in the case. (This leads me to believe that it could be a faulty temperature sensor on the motherboard.) Since I run Einstein-at-Home on this machine, I like to have it running at its highest speed possible, but I don’t want it to overheat and shut down.
To solve this problem I needed to make sure that “Cool n’ Quiet” was enabled in the machine’s BIOS. (That’s what’s it called on my AMD machine. On Intel machines, it’s called “SpeedStep”.) This will allow you to set the CPU speed from the command-line. (Note that this only works for newer processors.)
Then, I needed to install the “lm-sensors” package from the Linux distro repository. (Some distros have it named “lm_sensors”.)
The first time you run the “sensors” command, you may be prompted to let the program detect your motherboard’s sensors, and configure the proper kernel modules. After that, “sensors” will give you information about CPU temperature, and for some motherboards, overall system temperatures and fan speeds. (The output from each motherboard is different, so you would probably have to modify the following procedure somewhat to fit your own needs.)
To see system temperatures, just enter the command “sensors” for Celsius readings, or “sensors -f” for Fahrenheit readings.
Next, I wrote a script that saves the “sensors” output to a temporary text file, and uses a combination of “sed” and “cut” to extract the applicable information. An “if . . . then” construct will adjust the CPU speed accordingly.
In line 3, the “sensors -f > /tmp/sensors.txt” command will save the “sensors” output to a text file. The next line will extract the applicable temperature information and assign it to the “temperature” variable.
The CPU in this machine is a dual-core model, but for some reason the “sensors” command shows two temperature readings for each core. For some reason, the first reading for “Core1” is always the highest. That reading is on line 5 of the “sensors” output, so that’s the one I’ll want to use. To see only the contents of line 5, I use the command:
sed -n ’5p’ /tmp/sensors.txt
The actual temperature reading is in characters 14 through 16 of that line, so I’ll pipe the output of the “sed” command into “cut”.
cut -c14-16
Next, I’ll use command-substitution to assign the resultant value to the “temperature” variable.
temperature=$(sed -n ’5p’ /tmp/sensors.txt | cut -c14-16)
In the “if . . . then” construct, the contents within the square brackets will compare the actual temperature to the test value. Since we’re doing a numerical comparison, rather than a text-string comparison, we’ll have to use “-gt” and “-lt” instead of the normal greater-than and lesser-than symbols. The “if . . . then” will set the CPU speed down to 2.4 GHz if the CPU temperature rises to above 180 degree Fahrenheit, and will raise it back to 2.7 GHz if the temperature falls to below 100 degrees Fahrenheit. (If you’re wondering how the “+” sign affects a two-digit temperature reading, not to worry. The bash shell considers a positive number as either a stand-alone number, or a number with a “+” sign in front of it. Either way, the number is read properly, so we don’t have to worry about whether or not the “+” sign is there.)
I then saved the file as “too-hot.sh” in the “/usr/bin” directory. Since the speed selection utility requires root privileges, I then set up a cron job for the root user.
sudo crontab -u root -e
I set the job to run every seven minutes. (After some experimenting, I found that to be the ideal interval.)
Now, at times when the weather is somewhat cool, I can open a window in the room where this machine is located, and let the CPU cool down to the point that the script will kick up the CPU speed. When the weather warms back up, the script will kick the CPU back down. This script works like a champ, and I haven’t had a computer shutdown since I installed it.
This is just one real-life example of how to use text-stream filters to solve an everyday problem. With a little imagination, you could probably think of plenty more.
Written By Donnie Tevault
{ 4 comments }
Why not pipe the output of sensors to sed rather than going to a temp intermediate file?
temperature=(sensors -f | sed -n ’5p’ | cut -c14-16)
Another example of a stream filter is a filter which takes a file formatted with CRLF end-of-lines as for MSDOS and strips out the CR giving a file which only has the LF (as for Unix) end-of-line.
Have you ever popped the heatsink, cleaned and regreased it, and reinstalled? Has the system always been this way? It sounds like it’s missing the heatsink grease, or just a bad job of installation. If you’ve never done this before, make sure to search for some good instructions. (hint – less is more)
Why not run the “sensors -f” through sed directly like:
sensors -f | sed -n ’5p’ | cut -c14-16
Thanks.
{ 1 trackback }