3

I'm trying to make a shell script to use as an HDD temperature alert job with cron. The cron job must make these things:

  1. Verify the existing ATA devices (I'm using camcontrol);
  2. Verify the temperature of the devices identified (I'm using smartctl);
  3. Compare the temperatures of the ATA devices with a constant variable;
  4. If one of the devices temperature is highter than the constant variable, the script sends an email with the temperature of all ATA devices.

My problem is how to use the results of item 2 to accomplish the item 3...

My actual code is:

# Defines alert temperature
TEMP_MAX=30 #Graus celcius

# Create an array with devices
arrdiscs=($(camcontrol devlist | awk '{print substr($NF, 8, length($NF)-8)}'))

# Get the temperature of the devices
for i in "${arrdiscs[@]}"
do
  # Get temperatures
  TEMP="$(smartctl -A /dev/$i | egrep ^194 | awk '{print $10}')"
done

I can echo the devices names and the temperatures if I use:

for i in "${arrdiscs[@]}"
do
  TEMP="$(smartctl -A /dev/$i | egrep ^194 | awk '{print $10}')"
  echo "[$i]: $TEMP"
done

I tried (and many others ways):

for i in "${arrdiscs[@]}"
do
  TEMP="$(smartctl -A /dev/$i | egrep ^194 | awk '{print $10}')"
  echo "[$i]: $TEMP"
done

echo "ARRAY DISCOS: ${arrdiscs[*]}"
echo "TEMPERATURAS: ${TEMP[*]}"

The above code print the "arrdiscs" correctly but the "TEMP" prints null.

So... How can I create an array based on the TEMP variable so I can verify wich temperature is highter then TEMP_MAX?

Made some changes as suggested by Etan Reisner:

# Defines alert temperature
temp_max=20 #Graus celcius

# Monta array de discos do sistema
arrdiscs=($(camcontrol devlist | awk '{print substr($NF, 8, length($NF)-8)}'))
echo "${arrdiscs[@]}"

alertdiscs=()
for i in "${arrdiscs[@]}"
do
    temp=("$(smartctl -A "/dev/$i" | egrep ^194 | awk '{print $10}')")

    if [ -z "$temp" ]; then
      echo "\$temp is empty"
    else
      if [ $temp -gt $temp_max ]; then
          alertdiscs+=("[$i]: $temp")
          echo ${temp[@]}
      fi
    fi
done

if [ ${#alertdics[@]} -gt 0 ]; then
    echo "The following discs were too hot:"
    printf '%s\n' "${alertdiscs[@]}"
else
    echo "${alertdiscs[@]}"
fi

But I got the result as follow:

ada0 ada1 ada2 ada3 da0
33
31
32
30
$temp is empty
[ada0]: 33 [ada1]: 31 [ada2]: 32 [ada3]: 30

The variable temp_max was set to 20, but no "The following discs were too hot:" message displayed... :(

2
  • you have to create an array and add elements. it won't miraculously appear. Commented Apr 16, 2015 at 12:57
  • Oh! Seriously?! I thought the array would appear by divine work! Please, save us from comments that adds nothing to the discussion or to the solution of the problem... If you had at least bothered to read the title and all the text, you probably would not had put this comment... Thank you... for nothing... Commented Apr 17, 2015 at 0:48

1 Answer 1

2

You can create an array piecemeal like this:

temps=()
for i in "${arrdiscs[@]}"
do
    temps+=("$(smartctl -A "/dev/$i" | egrep ^194 | awk '{print $10}')")
done

echo "${temps[*]}"

That being said I would probably suggest keeping most of the temperatures local to the loop and only storing the alert-worthy temperatures (and disks) in an array suitable for use in the message at the end.

# Defines alert temperature
temp_max=30 #Graus celcius

alertdiscs=()
for i in "${arrdiscs[@]}"
do
    temp=("$(smartctl -A "/dev/$i" | egrep ^194 | awk '{print $10}')")
    if [ -n "$temp" ] && [ $temp -gt $temp_max ]; then
        alertdiscs+=("[$i]: $temp")
    fi
done

if [ ${#alertdiscs[@]} -gt 0 ]; then
    echo "The following discs were too hot:"
    printf '%s\n' "${alertdiscs[@]}"
fi
Sign up to request clarification or add additional context in comments.

5 Comments

Hi Etan! Thank you very much! But... If I have any disks that do not return its temperature, I get the error: [: -gt: unary operator expected I tryed to use unset but if I have more than one device withou temperature, it is useless. Can't use delete array[index] because the index could be any number depending of the system I run the script. I also tryed to use awk -F and sed but without success... Can you help me with that?
That's probably happening in the loop not after it. And yes, I didn't take that into account. Editing.
Very nice! Thank you again! But the last if isn't working... I edited my question with a new code and some results to help debug...
Typo in the variable name in the last if check. Just fixed it.
Thank you so much Etan Reisner! Worked like a charm!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.