-2

I have a script with following lines:

TIMESTAMP_END=$(date +"%s")
FILE=${DIR}/recording_$TIMESTAMP_BEGIN-$TIMESTAMP_END.$EXT
mv ${TMP_FILE} ${FILE}

Script is running on Raspberry Pi and the TIMESTAMP_END variable is than used as a part of filename represented by the variable FILE. I had two instances when the resulting variable was apparently an empty string, because FILE ended up being recording_1469556286-.mp3, the end timestamp is not present so I assume it was empty string. I cannot reproduce it.

What could possibly be the reason?

  • Please post some code so that we can have a better understanding of your problem. The line you provided doesn't have any issues and will produce the expected result 100% of the time, so the problem lies elsewhere in your code. – Charles D Pantoga Jul 26 '16 at 15:25
  • Variable is used on the next line, there really have to be some problem with date itself. I edited question. – Alexander Weps Jul 26 '16 at 17:59
  • Works fine for me, too. I blame Raspbian. – Michael Hampton Jul 26 '16 at 18:12
  • I works fine for me too. I had only two instances so far, but I would like to here some reasonable explanation why would date returned an empty string. – Alexander Weps Jul 26 '16 at 18:14
  • @AlexanderWeps please see my updated answer – Charles D Pantoga Jul 26 '16 at 18:32
  • I know that this is not an answer to why date is not working specifically, but what happens if you try replacing `FILE=${DIR}/recording_$TIMESTAMP_BEGIN-$TIMESTAMP_END.$EXT` with `FILE=${DIR}/recording_$TIMESTAMP_BEGIN-$(date +%s).$EXT`? if the only place `TIMESTAMP_END` is used occurs in the `FILES=...` line it seems like you could include the command without having to set the variable. – Matt Jul 26 '16 at 19:20
  • @Matt Sure, could do that, I usually use variable so I can also put some debug messages. – Alexander Weps Jul 28 '16 at 14:51
  • using `date` directly in this case seemed like a good way to test if the issue is related to an issue with the `date` command(which seems unlikely if one of the timestamps is displayed correctly) or the variable being referenced. I was merely suggesting using the command directly as a way to identify the root cause of the problem. Also is there a reason you use curly brackets for some variables but not for others, this answer kind of explains why doing so could be valuable http://stackoverflow.com/questions/8748831/when-do-we-need-curly-braces-in-variables-using-bash? – Matt Jul 29 '16 at 01:08

2 Answers2

2

EDIT:

My suspicion is that it's trying to expand a variable that doesn't exist. I'm almost certain that by wrapping all your variables with brackets (${TIMESTAMP_BEGIN}-${TIMESTAMP_END}) it will work as expected.

For instance, change the code to:

# set timestamp_end:
TIMESTAMP_END=$(date +%s)
# the following uses variable expansion to expand timestamp_end
# to unknown if the variable truly is unset. Replace `:-` with :=
# if you would like to assign the value "Unknown" to timestamp_end
# if timestamp_end is null or undefined.
FILE=${DIR}/recording_${TIMESTAMP_BEGIN}-${TIMESTAMP_END:-"Unknown"}.${EXT}
mv ${TMP_FILE} ${FILE}

This will output "Unknown" if the variable TIMESTAMP_END is really null or undefined, and you'll find out for sure if the problem is with date or if the problem is variable expansion working differently than you'd expect it to.


ORIGINAL POST:

Is it possible that you're setting the variable in one process and checking for it in another? Variables are only accessible to their own processes. If you're running a script that sets variables they won't be accessible to your terminal after you've used them unless you use source. I'll illustrate that with an example:

one.sh

#!/bin/bash

export onetime=$(date +%s)
echo "Time is: $onetime"

and in your terminal:

$ charlie on work-laptop in ~/test
❯❯ ./one.sh
Time is: 1469546203

$ charlie on work-laptop in ~/test
❯❯ echo $onetime


$ charlie on work-laptop in ~/test
❯❯ source one.sh
Time is: 1469546211

$ charlie on work-laptop in ~/test
❯❯ echo $onetime
1469546211

It's also important to note that if your script spawns any new processes, perhaps with a subshell for example, variables set in that new process won't be accessible outside of the process.

two.sh

#!/bin/bash

export var="[1st Value]"
echo "Var is $var"

(echo "Enter 1st subshell: "; var="[2nd Value]"; echo "=> Var is $var")
echo $var

(echo "Enter 2nd subshell: "; export var="[3rd Value]"; echo "=> Var is $var")
echo $var

and when we run this, the output is:

$ charlie on work-laptop in ~/test
❯❯ ./two.sh
Var is [1st Value]
Enter 1st subshell:
=> Var is [2nd Value]
[1st Value]
Enter 2nd subshell:
=> Var is [3rd Value]
[1st Value]
  • No, variable is set just before it is used in the same script. I really blame date itself so far. – Alexander Weps Jul 26 '16 at 17:55
  • Would the missing brackets explain why it works almost in all cases. But very rarely it doesn't? – Alexander Weps Jul 26 '16 at 18:51
  • This solution or something along these lines, e.g. unset variable, extra unexpected char in var name, or dangling quotations, seems plausible to me. If the script produces file names that are partially correct, with 1/2 correct datestamps as indicated in the question I have a hard time blaming `date` – Matt Aug 01 '16 at 19:26
  • It produced empty date 2 out of 1000 tries, I have hard time blaming other parts of the script. – Alexander Weps Aug 05 '16 at 21:05
  • @AlexanderWeps I know this was a long time ago but if you had just printed ${TIMESTAMP_END:-"Unknown"} it would have given an indication as to whether or not the variable is unset. Using an unset variable in bash will expand to an empty string which exhibits the exact same behavior you described in your problem. Furthermore if you had just run `set -x` to enable debugging in your script you would have seen exactly what the issue was. Hope you eventually got it solved despite not updating the thread. Probably because I was onto something with the variable thing lol. – Charles D Pantoga Jul 25 '23 at 12:37
1

You do not need the double quotes around the %s, date +%s should work. Also if the TIMESTAMP_END variable is used locally in the script and not exported as a global environmental variable some would recommend using lower case to help distinguish between local and global variables; if you are interested in that sort of stylistic change the result would be:

timestamp_end=$(date +%s)

Matt
  • 2,751
  • 1
  • 14
  • 20