3

I have been reading lines from a file I created and would like to use a variable and avoid writing to storage. Not sure if this can easily be done. The working code starts off as follows

sensors | grep "Core" > temp.tmp
input=./temp.tmp
while IFS= read -r line
do
--etc--
done < "$input"

The above works fine but I need to find a good location for the temp file and thought I could just avoid writing to storage altogether. Tried the following

input=`sensors | grep "Core"`
while IFS= read -r line
do
--etc--
done < "$input"

This did not work as the newline delimiters were removed and the variable has a huge "line" that is read in all at once. The variable string has ")" that end in the correct place to be used as a delimiter but the "read" keys on newline. Any easy fix?

..thanks for looking...

Joseph Stateson
  • 143
  • 3
  • 14
  • See also https://superuser.com/q/284187/4714, same question, similar answers. – glenn jackman Dec 12 '19 at 18:52
  • 1
    For future reference, the "right" place for the temp file is `/tmp/` and such things are usually done with `tmpFile=$(mktemp); command > "$tmpFile"`. – terdon Dec 12 '19 at 19:22

1 Answers1

5

You don't even need a variable, let alone a file:

sensors | grep "Core" | while IFS= read -r line
do
    command
done

But yes, you could also read from a variable:

input=$(sensors | grep Core)
$ while IFS= read -r line; do echo "$line"; done <<<"$input"
Core 0: +80.0°C (high = +100.0°C, crit = +100.0°C)
Core 1: +80.0°C (high = +100.0°C, crit = +100.0°C)
Core 2: +81.0°C (high = +100.0°C, crit = +100.0°C)
Core 3: +80.0°C (high = +100.0°C, crit = +100.0°C)

For more details on the <<< operator and its brethren see:

How to tell which parameter is being supplied to a command with a redirectioin operator?

What are the shell's control and redirection operators?

terdon
  • 98,183
  • 15
  • 197
  • 293
  • Thanks! That worked perfectly! BTW your temps seem way too high this time of year (at least in northern hemisphere) – Joseph Stateson Dec 12 '19 at 17:57
  • @JosephStateson thanks, but not for my CPU whose high (and critical) is 100 and which is now using a thermal paste last changed ~4 years ago ;) – terdon Dec 12 '19 at 18:02
  • There must be some side effect or scope loss inside the do ..done as I am losing contents of variables after the exit from done. May post this as a different problem. Possibly it is cause by using IFS=' ' read -r -a array <<< "$line" inside the block. Not sure what is happening – Joseph Stateson Dec 12 '19 at 19:10
  • @JosephStateson any variables defined in the while won't be available in outside it, no. Why are you trying to set an array, that's a very different proposition. Yes, please ask a new question. – terdon Dec 12 '19 at 19:19
  • Used array to get the (on your example) the 80.0 which is the 2nd element in the array. The variable is defined outside the block and is concatenated inside the block so the output is (for example) "CPU 4 80.0 80.0 81.0 80.0" after exiting the block. Unaccountably, it works fine and the string grows with each iteration, but after the "done" I am left with just "CPU 4 " which was defined way outside. Calling this from python, probably should have used python for everything as I had problems with the decimal in bash. Using python to send info to another system that reports temps – Joseph Stateson Dec 12 '19 at 19:30
  • @JosephStateson oh wow. Yes of course you should have used python, the shell is a horrible scripting tool. But the point is that anything done inside the while loop will not persist outside it. The while is running in its own subshell with its own copies of the variables. Any change you make to a variable in the while loop will be lost when the loop finishes. – terdon Dec 12 '19 at 19:40