Reputation: 21
When executing the below portion of my code, I am getting the error: syntax error: operand expected (error token is "/(60*60*24)")
# \function convertsecs2dhms
# \brief convert seconds to days hour min sec
#####################################################################################################################
function convertsecs2dhms()
{
((d=${1}/(60*60*24)))
((h=(${1}%(60*60*24))/(60*60)))
((m=(${1}%(60*60))/60))
((s=${1}%60))
printValue=`printf "%02d days %02d hours %02d minutes %02d seconds \n" $d $h $m $s`
printInfo "$printValue"
}
Here is the error that I am getting:
(standard_in) 1: syntax error
expr: syntax error
Estimated time for migration completion for server:-
./migration.sh: line 983: ((: d=/(60*60*24): syntax error: operand expected (error token is "/(60*60*24)")
./migration.sh: line 984: ((: h=(%(60*60*24))/(60*60): syntax error: operand expected (error token is "%(60*60*24))/(60*60)")
./migration.sh: line 985: ((: m=(%(60*60))/60: syntax error: operand expected (error token is "%(60*60))/60")
./migration.sh: line 986: ((: s=%60: syntax error: operand expected (error token is "%60")
00 days 00 hours 00 minutes 00 seconds
Upvotes: 1
Views: 2569
Reputation: 119
Extending the solution of kvantour for float-type inputs:
convertsec2dhms () {
date -d "@$1" -u "+$((${1%.*}/86400))-%H:%M:%S"
}
${1%.*}
converts the input from float to integer, see bash - How to convert floating point number to integer?.
For example:
$ ts=69854632
$ date -d "@$ts" -u "+$((${ts%.*}/86400))-%H:%M:%S"
808-12:03:52
$ ts=69854632.454
$ date -d "@$ts" -u "+$((${ts%.*}/86400))-%H:%M:%S"
808-12:03:52
The previous method raises an error for float-type inputs:
$ ts=69854632
$ date -d "@$ts" -u "+$(($ts/86400))-%H:%M:%S"
808-12:03:52
$ ts=69854632.454
$ date -d "@$ts" -u "+$(($ts/86400))-%H:%M:%S"
-bash: 69854632.454/86400: syntax error: invalid arithmetic operator (error token is ".454/86400")
Upvotes: 1
Reputation: 26481
This does not answer the question why you have these errors. The answer is given by tripleee. This answer gives you an alternative approach to achieve your goals.
What you might be interested in is the usage of the date
command
convertsec2dhms () {
date -d "@$1" "+$(($1/86400)) days and %H hours %M minutes %S seconds";
}
To get the number of days we do an integer division by 86400 seconds. The hours, minutes and seconds are obtained via the date command by assuming that the time is given in UNIX time (i.e. seconds since 1970-01-01T00:00:00).
note: you cannot use the day-of-year computation (%j
) as this will always give you an extra day (first of January is day 1 and not day 0).
$ convertsec2dhms 69854632
808 days and 12 hours 03 minutes 52 seconds
Upvotes: 2
Reputation: 189387
Just double parentheses are not sufficient to select arithmetic context in pure sh
.
# don't use non-portable "function" keyword
convertsecs2dhms () {
# use $((...)) for arithmetic
d=$((${1}/(60*60*24)))
h=$(((${1}%(60*60*24))/(60*60)))
m=$(((${1}%(60*60))/60))
s=$((${1}%60))
# use printf -v
printf -v printValue "%02d days %02d hours %02d minutes %02d seconds \n" $d $h $m $s
printInfo "$printValue"
}
See also https://mywiki.wooledge.org/ArithmeticExpression but notice that most of it describes Bash, not POSIX sh
.
Upvotes: 5