I'm trying to write a function that is supposed to convert a time stamp of the form hr:min:sec,ms (i.e 15:41:47,757) to milliseconds. The function is the following:
#!/bin/sh
mili () {
hr=$(echo "$1" | cut -c1-2)
echo "hr is: " $hr
min=$(echo "$1" | cut -c4-5)
echo "min is: " $min
sec=$(echo "$1" | cut -c7-8)
echo "sec is: " $sec
ms=$(echo "$1" | cut -c10-12)
echo "ms is: " $ms
total=$(($hr \* 3600 + $min \* 60 + $sec) \* 1000 + $ms)
return "$total"
#echo "Result is: "$total" "
}
mili $1
However, when I run it:
./mili.sh "15:41:47,757"
I get the following output message:
./mili.sh: command substitution: line 15: syntax error near unexpected token
`\*'
./mili.sh: command substitution: line 15: `($hr \* 3600 + $min \* 60 + $sec)
\* 1000 + $ms'
./mili.sh: line 17: return: : numeric argument required
I've tried variations of expr with and without single quotes, double quotes, and backticks but can never seem to get it to compute the arithmetic. I can confirm a simple command like this works: expr 2 * 3 but when I try to use something similar in my script it fails.
How can I get it to simply compute my expression?
Inside arithmetic, *
does not need to be escaped. Also, some parentheses were missing. Thus, replace:
total=$(($hr \* 3600 + $min \* 60 + $sec) \* 1000 + $ms)
With:
total=$((($hr * 3600 + $min * 60 + $sec) * 1000 + $ms))
The code can be simplified avoiding the need for multiple calls to cut
:
mili() {
IFS=':,' read hr min sec ms <<<"$1"
echo "hr is: " $hr
echo "min is: " $min
echo "sec is: " $sec
echo "ms is: " $ms
total=$((($hr * 3600 + $min * 60 + $sec) * 1000 + $ms))
echo "Total=$total"
return "$total"
}
In a Bash arithmetic context, the dollar sign before a variable is optional. For example:
$ a=1; echo "$((1 + a)) and $((1+ $a))"
2 and 2
While some style guides recommend omitting $
in an arithmetic context, there is a key difference. As Chepner points out in the comments, the treatment of undefined variables is very different:
$ unset a
$ echo $((1 + $a))
bash: 1 + : syntax error: operand expected (error token is "+ ")
$ echo $((1 + a))
1
In summary:
If you want an undefined variable to default to zero, then omit the $
.
If you want an undefined variable to be replace with nothing, possibly causing an invalid expression, then include the $
.
In the shell function mili
, an undefined variable hr
, min
, etc., would indicate a code error and we might want an error message to warn us about it and we would want to include the $
. In other circumstances where a default value of zero is reasonable, we would not and omitting the $
would be correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With