3

I'm trying to make this temperature log in Raspberry Pi happen (though some of the code did not work therefore I used slightly diff. solutions):

https://www.raspberrypi.org/learning/temperature-log/worksheet/

I'm stuck with writing the results in a file. I want to create a file that's name contains the actual date, e.g. temperature_log_2016_08_13.txt

When running the script I get an ambiguous redirection error each time lines with the echo commands execute. I tried all sort of combinations with quotes, double-quotes, no quotes. Pls advice.

#!/bin/bash

timestamp() {
    date +%F_%H-%M-%S
}

temperature() {
    /opt/vc/bin/vcgencmd measure_temp
}

temp=$(temperature)
temp2=${temp:5:9}

echo Temperature Log_$(date) >/home/pi/logs/temperature_log_$(date).txt

for i in {1..5}
do
    echo ${temp2} $(timestamp) >>/home/pi/logs/temperature_log_$(date).txt
    sleep 1
done

UPDATE: by putting the file name between quotation marks, as advised below, the ambiguous redirect error is gone, but instead the script produces 5 files with the date/timestamp in its name. I need only 1 file into which all the temperatures are written.

Gabor
  • 43
  • 1
  • 1
  • 5
  • Putting `>filename` or `>>filename` on a command opens that file before that command, and closes it when the command is done. It's very inefficient to do that over and over (or inside a loop), compared to opening the file just once and reusing that handle across multiple commands. – Charles Duffy Aug 13 '16 at 23:06
  • ...if, for instance, you put `exec >"/home/pi/logs/temperature_log_$(date).txt"` only once, at the top of your script, you'd *both* avoid the name changing over the course of execution, and *also* avoid the inefficiency of re-opening the file over and over. – Charles Duffy Aug 13 '16 at 23:07

2 Answers2

4

The $(date) in your example produces a timestamp with blanks. You might either use your function ($(timestamp)) instead, or quote the whole target filename (or both):

echo bla >> "/home/pi/logs/temperature_log_$(timestamp).txt"

And it is best to actually evaluate the timestamp in the filename only before the loop, otherwise you get a new file every second or minute:

# %F: full date; same as %Y-%m-%d
logfile = "/home/pi/logs/temperature_log_$(date +%F).txt" 
echo "Temperature Log_$(date)" > "$logfile" # overwrite if started 2 times a day
for i in {1..5}
do
    temp=$(/opt/vc/bin/vcgencmd measure_temp)
    temp=${temp:5:9}
    echo "${temp} $(timestamp)" >> "$logfile"
    sleep 1
done
eckes
  • 10,103
  • 1
  • 59
  • 71
  • 2
    And you'll find the files with a date format like `$(date +%Y-%m-%d_%H.%M.%S)` will automatically sort easily either from oldest date or newest date, making it much easier to manipulate those files for data extraction (if ever needed). Good luck to all! – shellter Aug 13 '16 at 21:00
  • Thanks, now I don't get the ambiguous redirect error anymore, instead the script produces 5 files with the date/timestamp in its name. I need only 1 file into which all the temperatures are written. – Gabor Aug 13 '16 at 21:04
  • 1
    Replace `$(date)` with `$(date +%F)` – Dusan Bajic Aug 13 '16 at 21:26
  • Expanded the answer with pre-computing the filename, which avoids its rollover and reduces the number of forks. – eckes Aug 13 '16 at 22:31
2

Output of date contains spaces. You need to doublequote the filename to make the spaces part of it:

echo Temperature Log_$(date) > "/home/pi/logs/temperature_log_$(date).txt"

Or use your function, but quoting the file name is a good habit anyway.

choroba
  • 231,213
  • 25
  • 204
  • 289
  • Thanks, now I don't get the ambiguous redirect error anymore, instead the script produces 5 files with the date/timestamp in its name. I need only 1 file into which all the temperatures are written. – Gabor Aug 13 '16 at 21:05
  • @Gabor: Then store the date in a variable and use it, so it doesn't change with the next second. `date=$(date)` and later `echo ... > "/path/$date.txt"` – choroba Aug 13 '16 at 21:24