Subtracting dates formats in bash

Я пытаюсь создать обратный отсчет - скорее всего, трудный путь. У меня это настроено так:

#! /bin/bash 

#When to execute command 
execute=$(date +"%T" -d "22:30:00")

#Current time
time=$(date +"%T")

#Subtract one from the other.... the below is line 11
math=$(("$execute"-"$time"))

#Repeat until time is 22:30:00
until [ "$math" == "00:00:00" ]; do  

echo "Countdown is stopping in $math"
sleep 1
clear 
done

Проблема в том ... Это не работает. Вот вывод в терминале:

   /path/to/file/test.sh: line 11: 22:30:00-16:39:22: syntax error in expression (error token is “:30:00-16:39:22”) 
    Countdown is stopping in 

Во-первых, сообщение об ошибке, что не так?

Во-вторых, сообщение «Обратный отсчет останавливается» должно содержать часы, минуты и секунды, в которых обратный отсчет прекратится. Почему нет? не так ли? Имейте в виду, я не профессионал.

2
задан 9 July 2020 в 01:42

2 ответа

Проблема в операторе

math=$(("$execute"-"$time"))

, поскольку выполняет и время содержат значения в формате % H:% M:% S . Но арифметическое расширение bash не может оценивать форматы времени.

Вместо формата % H:% M:% S можно преобразовать время в секунды, выполнить арифметику, а затем распечатайте в нужном формате.

Что-то вроде

#!/bin/bash

#When to execute command
execute=$(date +"%s" -d "22:30:00")

time=$(date +"%s")
math=$((execute-time))

if [[ $math -le 0 ]]; then
    echo "Target time is past already."
    exit 0
fi

#Repeat until time is 22:30:00
while [[ $math -gt 0 ]]; do
    printf "Countdown is stopping in %02d:%02d:%02d" $((math/3600)) $(((math/60)%60)) $((math%60))
    sleep 1
    clear

    # Reset count down using current time;
    # An alternative is to decrease 'math' value but that
    # may be less precise as it doesn't take the loop execution time into account
    time=$(date +"%s")
    math=$((execute-time))
done
1
ответ дан 30 July 2020 в 22:11

Спасибо, @PP за ответ. Сначала ваш метод работал, но перестал работать после перезагрузки .... Кроме того, он не остановил цикл - это означало, что он перешел в отрицательные числа и впоследствии никогда не выполнял команды. Вот что я в итоге сделал:

#! /bin/bash

#When to execute command
execute=$(date +"%s" -d "22:30:00")

time=$(date +"%s")
math=$((execute-time))

#Repeat until time is 22:30:00
until [ "$time" == "$execute" ]; do
    printf "The server will stop in %02d:%02d:%02d" $((math/3600)) $(((math/60)%60)) $((math%60))
    sleep 1
    clear

    # Reset count down using current time;
    # An alternative is to decrease 'math' value but that
    # may be less precise as it doesn't take the loop execution into account
    time=$(date +"%s")
    math=$((execute-time))

if [ "$time" == "$execute" ]; then

break
fi 

done 

echo "Cycle has ended"
1
ответ дан 30 July 2020 в 22:11

Другие вопросы по тегам:

Похожие вопросы: