Таймер для одновременной настройки различных сигналов тревоги

Перейдите на страницу веб-администрирования вашего шлюза и выполните поиск «переадресации портов» или «виртуального сервера»: шлюзу необходимо перенаправить пакеты на данный порт, например порт 22, на ваш внутренний IP-адрес.

Предположим, вы можете выбрать сервис из списка, ssh должен быть там. Затем вставьте внутренний IP-адрес вашего устройства в текстовое поле «IP-адрес сервера».

Для служб, не входящих в список, вы должны выбрать «Пользовательский сервер», я полагаю, что диалог изменится, чтобы вы могли ввести номер порта.

Для dyndns ваш шлюз может иметь поддержку (см. справку или документ шлюза), или вы можете использовать какое-то программное обеспечение на своем хосте для информирования о динамических изменениях внешнего IP-адреса.

4
задан 5 June 2018 в 11:46

3 ответа

multi-timer bash script

Скрипт multi-timer bash работает в версиях Ubuntu 14.04, 16.04 и 18.04. Он также работает в Windows 10 с установленным Ubuntu 16.04 Desktop.

Он имеет функции:

Сохраняет конфигурацию между режимами использования. В наборе последовательно выполняется до 19 таймеров. Индикатор выполнения для каждого таймера. Набор таймеров можно запускать несколько раз. Индикатор выполнения для набора. Индикатор выполнения для всех наборов. Необязательное приглашение начать каждый таймер и / или установить. Дополнительное всплывающее сообщение, когда каждый таймер и / или набор заканчиваются. Дополнительный сигнал тревоги, когда каждый таймер и / или набор заканчиваются. Дополнительный экран блокировки, когда каждый таймер ИЛИ установлен ИЛИ все наборы заканчиваются. Дополнительный интерфейс для индикатора Sysmonitor, поэтому Systray показывает обратный отсчет. Дополнительный закрытие индикатора выполнения, когда все таймеры завершаются.

Требуется пакет yad sudo apt install yad

Вкладка «Конфигурация ноутбука»

yad (Еще один диалог) имеет функцию, которая позволяет полям multi-timer

Y позволяет вам:

Сохраняет конфигурацию между использованием. определить, сколько раз запускать набор таймеров. До 19 таймеров последовательно запускаются в комплекте. опция блокировки экрана в конце каждого таймера, набора или всех наборов Полоса хода для каждого таймера.

Вкладка «Таймеры для ноутбуков»

Вкладка «Таймеры» позволяет:

определить, сколько раз запускать набор таймеров. Установите количество секунд или минут каждого таймера.

Отображение индикатора хода

Поскольку multi-timer подсчитывает индикаторы выполнения, используются для:

Установите количество секунд или минут каждого таймера. опция блокировки экрана в конце каждого таймера, установки или всех наборов всех наборов (если запускаются два или более набора)

multi-timer configuration.png [!d33]

Bash Script

Скопируйте и вставьте скрипт bash ниже в имя файла multi-timer. Я предлагаю каталог /home/<your_user_name>/bin/. Затем пометьте скрипт как исполняемый файл, используя:

chmod a+x /home/<your_user_name>/bin/multi-timer

Изменение количества таймеров

В строках с номерами 78, 79 и 80 вы увидите следующее:

# No. of timers default is 17 for 768 line screen and TMR_DURATION_NDX is 30
TMR_DURATION_NDX=30 # Set to 28 for 800x600 screen, 32 for 1920x1080 screen
MAX_TIMERS=17       # Set to 15 for 800x600 screen, 19 for 1920x1080 screen

Несмотря на то, что поддерживается 19 таймеров, они могут помещаться только на экран 1920x1080. Около 17 (настройка по умолчанию) будет помещаться на среднем экране 1024x768. Если у вас есть Super VGA с разрешением 800x600, вы можете получить только от 13 до 15 таймеров.

Вы должны изменить значения на линиях 85 & amp; 86 в то же время:

Bash field name    ----------- Values to assign ---------
TMR_DURATION_NDX   23  24  25  26  27  28  29  30  31  32
MAX_TIMERS         10  11  12  13  14  15  16  17  18  19

Например, если вы хотите не более 12 таймеров, установите TMR_DURATION_NDX=25 и MAX_TIMERS=12.

После изменения индекса и максимума сохраните multi-timer. Если вы уже запустили программу, как только файл конфигурации может быть создан, его нужно будет удалить. Используйте эту команду для удаления старого файла конфигурации:

`rm ~/.multi-timer`

Обратите внимание, что ~/ является короткой вырезкой в ​​вашем домашнем каталоге, то есть /home/your_user_name/.

Код Bash для [ f20]

#!/bin/bash

# NAME: multi-timer
# DESC: Multiple timers countdown with alarm.
#       https://askubuntu.com/questions/1039357
#       /a-timer-to-set-up-different-alarms-simultaneosly

# DATE: May 31, 2018. Modified June 7, 2018.

# UPDT: 2018-06-07 Add new index for check box: "automatically close
#           progress bar display when all Sets finish. Use: rm ~/.multi-timer
#           to delete configuration file before running update.

# NOTE: Following conventions are used:
#           Functions must be defined above point where they are called.
#           Yad style TRUE/FALSE instead of Bash true/false convention.
#           Variables beginning with- s is string
#                                   - i is integer
#                                   - f is TRUE/FALSE
#                                   - a is array
#                                   - cb is combobox

# Must have the yad package.
command -v yad >/dev/null 2>&1 || { echo >&2 \
        "yad package required but it is not installed.  Aborting."; \
        exit 99; }

# Running under WSL (Windows Subsystem for Linux)?
if grep -Fxq "Microsoft" /proc/version; then
#if cat /proc/version | grep Microsoft; then
    fWindows10=true
else
    fWindows10=false
fi

# On Skylake i7-6700HQ .467 seconds lost over 20 minutes incl writing to file.
if [[ "$1" == "-l" ]] || [[ "$1" == "--log-lost-time" ]] ; then
    fLog=TRUE
else
    fLog=FALSE
fi

KEY="12345"     # Key for tying Notebook pages (tabs) together
OIFS=$IFS;      # Save current IFS (Input File Separator)
IFS="|";        # Yad fields and Bash array indices separated by `|`
aMulti=()       # Main array for storing configuration
# Temporary files for Notebook output
res1=$(mktemp --tmpdir iface1.XXXXXXXX) # Notebook Configuraion Page (Tab 1)
res2=$(mktemp --tmpdir iface2.XXXXXXXX) # Notebook Timers Page (Tab 2)

Cleanup () {
    rm -f "$res1" "$res2"               # Remove temporary files
    IFS=$OIFS;                          # Retore Input File Separator
    if [[ -f ~/.lock-screen-timer-remaining ]]; then
        # Remove Sysmonitor Indicator interface file.
        rm -f ~/.lock-screen-timer-remaining
    fi
}

# Comboboxes, constants and Index offsets
cbTimeUnits="Seconds!Minutes"
cbLockScreen="Never!Each timer end!Each set end!All sets end"

TIME_UNIT_NDX=0
SET_COUNT_NDX=1
PROGRESS_INTERVAL_NDX=2
ALARM_FILENAME_NDX=3
LOCK_SCREEN_NDX=4
PROMPT_BEFORE_TIMER_NDX=5
END_TIMER_MESSAGE_NDX=6
END_TIMER_ALARM_NDX=7
PROMPT_BEFORE_SET_NDX=8
END_SET_MESSAGE_NDX=9
END_SET_ALARM_NDX=10
SYSMONITOR_INDICATOR_NDX=11
CLOSE_PROGRAM_AT_END_NDX=12
TMR_ALIAS_NDX=13
# No. of timers default is 17 for 768 line screen and TMR_DURATION_NDX is 30
TMR_DURATION_NDX=30 # Set to 28 for 800x600 screen, 32 for 1920x1080 screen
MAX_TIMERS=17       # Set to 15 for 800x600 screen, 19 for 1920x1080 screen

ReadConfiguration () {

    if [[ -s ~/.multi-timer ]]; then
        read -ra aMulti < ~/.multi-timer
        for (( i=0; i<MAX_TIMERS; i++ )); do
            aAlias[i]="${aMulti[ i+TMR_ALIAS_NDX ]}"
            aDuration[i]="${aMulti[ i+TMR_DURATION_NDX ]}"
        done
        # Set Combobox default with ^ prefix
        Str="${aMulti[TIME_UNIT_NDX]}"
        cbTimeUnits="${cbTimeUnits/$Str/\^$Str}"
        Str="${aMulti[LOCK_SCREEN_NDX]}"
        cbLockScreen="${cbLockScreen/$Str/\^$Str}"
    else
        # Create new file
        aMulti[TIME_UNIT_NDX]="Seconds"
        aMulti[SET_COUNT_NDX]=1
        aMulti[PROGRESS_INTERVAL_NDX]=1
        aMulti[ALARM_FILENAME_NDX]="/usr/share/sounds/freedesktop/stereo/complete.oga"
        aMulti[LOCK_SCREEN_NDX]="Never"
        aMulti[PROMPT_BEFORE_TIMER_NDX]="FALSE"
        aMulti[END_TIMER_MESSAGE_NDX]="FALSE"
        aMulti[END_TIMER_ALARM_NDX]="TRUE"
        aMulti[PROMPT_BEFORE_SET_NDX]="FALSE"
        aMulti[END_SET_MESSAGE_NDX]="FALSE"
        aMulti[END_SET_ALARM_NDX]="FALSE"
        aMulti[SYSMONITOR_INDICATOR_NDX]="FALSE"
        aMulti[CLOSE_PROGRAM_AT_END_NDX]="FALSE"
        aAlias=("Timer 1" "Timer 2" "Timer 3" "Timer 4" "Timer 5" \
                "Timer 6" "Timer 7" "Timer 8" "Timer 9" "Timer 10" \
                "Timer 11" "Timer 12" "Timer 13" "Timer 14" "Timer 15" \
                "Timer 16" "Timer 17" "Timer 18" "Timer 19")
        aDuration=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    fi

}

BuildTimerPage () {

    aTimerPage=()
    for ((i=0; i<MAX_TIMERS; i++)); do
        b1=$(( i + 1 ))
        aTimerPage+=("--field=Timer $b1 Alias:")
        aTimerPage+=("${aAlias[i]}")
    done
    for ((i=0; i<MAX_TIMERS; i++)); do
        aTimerPage+=("--field=Duration::NUM")
        aTimerPage+=("${aDuration[i]}")
    done
}

GetParameters () {

    # configuration notebook page
    yad --plug=$KEY --tabnum=1 --form \
    --field="Timer duration units::CB" "$cbTimeUnits" \
    --field="Number of times to run set (all timers)::NUM" \
            "${aMulti[SET_COUNT_NDX]}"!1..99!1!0 \
    --field="Progress Bar update every x seconds::NUM" \
            "${aMulti[PROGRESS_INTERVAL_NDX]}"!1..60!1!0 \
    --field="Alarm sound filename:FL" "${aMulti[ALARM_FILENAME_NDX]}" \
    --field="Lock screen::CB" "$cbLockScreen" \
    --field="Ask to begin each timer:CHK" \
            "${aMulti[PROMPT_BEFORE_TIMER_NDX]}" \
    --field="Pop-up message when each timer ends:CHK" \
            "${aMulti[END_TIMER_MESSAGE_NDX]}" \
    --field="Sound alarm when each timer ends:CHK" \
            "${aMulti[END_TIMER_ALARM_NDX]}" \
    --field="Ask to begin each set (all timers):CHK" \
            "${aMulti[PROMPT_BEFORE_SET_NDX]}" \
    --field="Pop-up message when each set ends:CHK" \
            "${aMulti[END_SET_MESSAGE_NDX]}" \
    --field="Sound alarm when each set ends:CHK" \
            "${aMulti[END_SET_ALARM_NDX]}" \
    --field="Interface to Sysmonitor Indicator:CHK" \
            "${aMulti[SYSMONITOR_INDICATOR_NDX]}" \
    --field="Auto close progress bar display when all sets end:CHK" \
            "${aMulti[CLOSE_PROGRAM_AT_END_NDX]}" > "$res1" &

    # timers notebook page
    BuildTimerPage
    yad --plug=$KEY --tabnum=2 --form --columns=2 \
        "${aTimerPage[@]}" > "$res2" &

    # run main dialog
    #  --image=gnome-calculator
    if yad --notebook --key=$KEY --tab="Configuration" --tab="Timers" \
        --image=/usr/share/icons/gnome/48x48/status/appointment-soon.png \
        --title="multi-timer setup" --auto-close \
        --width=400 --image-on-top --text="Multiple Timer settings"
    then

        # When LC_NUMERIC=it_IT-UTF8 30 seconds can be `30,000000` or
        # `30.000000` which breaks bash tests for `-gt 0`.
        # Search and replace ".000000" or ",000000" to null
        sed -i 's/[,.]000000//g' "$res1"
        sed -i 's/[,.]000000//g' "$res2"

        # Save configuration
        truncate -s -1 "$res1" # Remove new line at EOF
        cat "$res1" >  ~/.multi-timer
        truncate -s -2 "$res2" # Remove trailing "|" and new line at EOF
        cat "$res2" >> ~/.multi-timer
        # Get user changes into aAlias & aDuration
        ReadConfiguration
        return 0
    else
        return 1    # Cancel click or Escape press
    fi

}

fNewRun=FALSE
fNewTimer=FALSE
iSetSaveSec=0

InitTimers () {

    if [[ "${aMulti[TIME_UNIT_NDX]}" == "Seconds" ]]; then
        fUnitsInSeconds=TRUE
    else
        fUnitsInSeconds=FALSE
    fi

    iActiveTimersCount=0
    for ((i=0; i<MAX_TIMERS; i++)); do
        if [[ ${aDuration[i]} -gt 0 ]] ; then
            (( iActiveTimersCount++ ))
            iSetSaveSec=$(( iSetSaveSec + ${aDuration[i]} ))
        fi
    done

    # Progress Bars, 1 per timer + optional: set and/or set count
    iAllSetsSaveCount="${aMulti[SET_COUNT_NDX]}"
    iAllSetsRemainingCount=$iAllSetsSaveCount
    fSetProgressBar=FALSE # Summary progress bar when > 1 timer used
    iSetProgressBarNo=0
    fAllSetsProgressBar=FALSE  # Summary progress bar when > 1 run
    iAllSetsProgressBarNo=0
    if [[ $iActiveTimersCount -eq 0 ]]; then
        # If active timers count = 0, error message & clear run count
        yad --title "mutli-timer error" --center --text \
            "At least one non-zero timer required." --image=dialog-error \
            --on-top --borders=20 --button=gtk-close:0
        iAllSetsRemainingCount=0 # Set orderly exit via sibling function(s)
        iProgressBarCount=0
        fAbend=TRUE
    else
        # Active timers count > 0 so calculate times
        fNewTimer=TRUE
        fNewRun=TRUE
        [[ $fUnitsInSeconds == FALSE ]] && \
            iSetSaveSec=$(( iSetSaveSec * 60 ))
        iAllSetsSaveCountSec=$(( iSetSaveSec * iAllSetsRemainingCount ))
        iAllSetsElapsedSec=0
        iProgressBarCount=$iActiveTimersCount
        if [[ $iActiveTimersCount -gt 1 ]]; then
            (( iProgressBarCount++ )) # Extra progress bar for Set
            fSetProgressBar=TRUE
            iSetProgressBarNo=$iProgressBarCount
        fi
        if [[ $iAllSetsRemainingCount -gt 1 ]]; then
            (( iProgressBarCount++ )) # Extra progress bar for Set Count
            fAllSetsProgressBar=TRUE
            iAllSetsProgressBarNo=$iProgressBarCount
        fi
    fi

    # Friendly variable names instead of Array entries
    iProgressSleepSeconds="${aMulti[PROGRESS_INTERVAL_NDX]}"
    sSoundFilename="${aMulti[ALARM_FILENAME_NDX]}"
    fPromptBeforeTimer="${aMulti[PROMPT_BEFORE_TIMER_NDX]}"
    fEndTimerMessage="${aMulti[END_TIMER_MESSAGE_NDX]}"
    fEndTimerAlarm="${aMulti[END_TIMER_ALARM_NDX]}"
    fPromptBeforeSetRun="${aMulti[PROMPT_BEFORE_SET_NDX]}"
    fEndSetMessage="${aMulti[END_SET_MESSAGE_NDX]}"
    fEndSetAlarm="${aMulti[END_SET_ALARM_NDX]}"
    fSysmonitorIndicator="${aMulti[SYSMONITOR_INDICATOR_NDX]}"
    fCloseProgramAtEnd="${aMulti[CLOSE_PROGRAM_AT_END_NDX]}"
}

# Optional lost time log file monitors program execution time for progress
# bars
[[ $fLog == TRUE ]] && echo "multi-timer lost time log"  > ~/multi-timer.log

PromptToStart () {

    # $1= Message key text
    # Dialog box to proceed with timer.
    yad --title "mutli-timer notification" --center --on-top \
        --fontname="Serif bold italic 28" \
        --text "Ready to start $1" \
        --image=/usr/share/icons/gnome/48x48/status/appointment-soon.png \
        --borders=20 --button=gtk-execute:0

    LastWakeMicroSeconds=$(date +%s%N) # Eliminate time waiting for user
}

EndMessageAndAlarm () {

    # $1= fEndTimerMessage, $2= fEndTimerAlarm, $3= Message key text

    # Sound alarm when timer ends
    if [[ "$2" == TRUE ]]; then
        if [[ ! -f "$sSoundFilename" ]]; then
        notify-send --urgency=critical "multi-timer" \
            --icon=/usr/share/icons/gnome/48x48/status/appointment-soon.png \
            "Sound file not found: $sSoundFilename"
        elif [[ $fWindows10 == TRUE ]]; then  
            powershell.exe -c '(New-Object Media.SoundPlayer "$sSoundFilename").PlaySync();'
        else
            paplay "$sSoundFilename" ;
        fi
    fi

    # Bubble message when timer ends
    if [[ "$1" == TRUE ]]; then
        notify-send --urgency=critical "multi-timer" \
            --icon=/usr/share/icons/gnome/48x48/status/appointment-soon.png \
            "$3 has ended."
        # Something bold to test. Set $3 has ended. into $phrase
        # /usr/bin/notify-send  --urgency=critical --icon=clock -t 4000 \
        # "<i>Time Now</i>" "<span color='#57dafd' font='26px'><i><b>$phrase</b></i></span>" >/dev/null 2>&1

    fi
}

LockScreenCheck () {

    # $1=Run type being checked:
    # "Each timer end" / "Each set end" / "All sets end"
    [[ "$1" != "${aMulti[$LOCK_SCREEN_NDX]}" ]] && return 0

    # When locking screen override & prompt to start next timer / run
    [[ "$1" == "Each timer end" ]] && fPromptBeforeTimer=TRUE
    [[ "$1" == "Each set end"   ]] && fPromptBeforeSetRun=TRUE

    if [[ $fWindows10 == TRUE ]]; then  
        # Call lock screen for Windows 10
        rundll32.exe user32.dll,LockWorkStation
    else
        # Call screen saver lock for Unbuntu versions >= 14.04.
        dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock
    fi
}

iCurrTimerNo=0
iCurrTimerNdx=0
TotalLostTime=0

PrepareNewSet () {

    # Was a set just completed?
    if [[ $iAllSetsRemainingCount -ne $iAllSetsSaveCount ]]; then
        # Display mssage and/or sound alarm for set end
        EndMessageAndAlarm $fEndSetMessage $fEndSetAlarm \
                           "$sSetProgressText"
        # Check to lock screen
        LockScreenCheck "Each set end"
    fi

    if [[ $iAllSetsRemainingCount -eq 0 ]]; then
        # We are done. Force exit from all while loops.
        fNewRun=FALSE
        fNewTimer=FALSE
    else
        # Decrement remaining run count and start at first timer.
        (( iAllSetsRemainingCount-- ))
        iSetElapsedSec=0
        fNewTimer=TRUE
        iCurrTimerNo=0
        iCurrTimerNdx=0
        iNextTimerNdx=0
        iCurrSetNo=$(( iAllSetsSaveCount - iAllSetsRemainingCount ))
        sSetProgressText="Set $iCurrSetNo of $iAllSetsSaveCount"
        [[ $fPromptBeforeSetRun == TRUE ]] && \
            PromptToStart "$sSetProgressText"
    fi
}

PrepareNewTimer () {

    iCurrTimerElapsedSec=0
    if [[ $iCurrTimerNo -eq $iActiveTimersCount ]]; then
        # Last timer done. Force exit from inner while loop.
        fNewTimer=FALSE
        return 0
    fi

    for ((i=iNextTimerNdx; i<MAX_TIMERS; i++ )); do
        if [[ ${aDuration[i]} -gt 0 ]]; then
            iCurrTimerNdx=$i
            (( iCurrTimerNo++ ))    # Increment progress bar number
            iNextTimerNdx=$(( iCurrTimerNdx + 1 ))
            iCurrTimerSaveSec=${aDuration[i]}
            [[ $fUnitsInSeconds == FALSE ]] && \
                            iCurrTimerSaveSec=$(( iCurrTimerSaveSec * 60 ))
            iCurrTimerRemainingSec=$iCurrTimerSaveSec
            break
        fi
    done
}

# Next function could be embedded within InitTimers to save space
# and code line count but this provides better readability IMO.
SetupYadProgressBars () {

    aYadProgressBars=("yad" "--multi-progress" "--center")
    aYadProgressBars+=("--title=multi-timer progress")
    [[ $fCloseProgramAtEnd == TRUE ]] && aYadProgressBars+=("--auto-close")
    aYadProgressBars+=("--auto-kill" "--watch-bar$iProgressBarCount")

    for ((i=0; i<MAX_TIMERS; i++)); do
        if [[ ${aDuration[i]} -gt 0 ]] ; then
            b1=$(( i + 1 ))
            aYadProgressBars+=("--bar=Timer $b1 - ${aAlias[i]}:NORM")
        fi
    done

    if [[ $fSetProgressBar == TRUE ]]; then
        aYadProgressBars+=("--bar=Set:NORM")
    fi
    if [[ $fAllSetsProgressBar == TRUE ]]; then
        aYadProgressBars+=("--bar=All Sets:NORM")
    fi
}

DisplayProgressBar () {

    # Parameters
    # $1=Elapsed Time, $2=Total Time, $3=Bar Number, 
    # $4=TRUE/FALSE if eligible to update Sysmonitor Indicator
    # $5=Sysmonitor Indicator text for interface file or null
    # $6=Progress Text Prefix, ie "Set 2 of 4: " or null
    iPercentage=$(( $1 * 100 / $2 ))
    echo "$3:$iPercentage"

    RemainingSec=$(( $2 - $1 ))
    h=$((RemainingSec/3600))
    m=$(((RemainingSec%3600)/60))
    s=$((RemainingSec%60))

    TimeRemaining=""
    [[ $h -gt 0 ]] && TimeRemaining=$TimeRemaining" $h Hours"
    [[ $m -gt 0 ]] && TimeRemaining=$TimeRemaining" $m Minutes"
    [[ $s -gt 0 ]] && TimeRemaining=$TimeRemaining" $s Seconds"
    if [[ $TimeRemaining == "" ]]; then
        echo "$3:#$6Finished."
    else
        echo "$3:#$6$TimeRemaining remaining."
    fi

    if [[ $fSysmonitorIndicator == TRUE ]] && [[ $4 == TRUE ]]; then
        echo "$5: $TimeRemaining" > ~/.lock-screen-timer-remaining
    fi
}

ProcessCurrTimer () {

    sTimerAlias="${aAlias[iCurrTimerNdx]}"

    # Dialog box to proceed with timer.
    [[ $fPromptBeforeTimer == TRUE ]] && PromptToStart "$sTimerAlias"

    iLastSleepSec=0
    [[ $fLog == TRUE ]] && echo Start timer: "${aAlias[iCurrTimerNdx]}" \
        >> ~/multi-timer.log

    while [[ $iCurrTimerElapsedSec -lt $iCurrTimerSaveSec ]]; do

        iCurrTimerElapsedSec=$(( iCurrTimerElapsedSec + iLastSleepSec))
        iSetElapsedSec=$(( iSetElapsedSec + iLastSleepSec))
        iAllSetsElapsedSec=$(( iAllSetsElapsedSec + iLastSleepSec))

        DisplayProgressBar $iCurrTimerElapsedSec $iCurrTimerSaveSec \
            $iCurrTimerNo TRUE "${aAlias[iCurrTimerNdx]}" "" ""
        if [[ $fSetProgressBar == TRUE ]] ; then
            DisplayProgressBar $iSetElapsedSec $iSetSaveSec \
                           $iSetProgressBarNo FALSE "" "$sSetProgressText: "
        fi
        [[ $fAllSetsProgressBar == TRUE ]] && \
            DisplayProgressBar $iAllSetsElapsedSec $iAllSetsSaveCountSec \
                           $iAllSetsProgressBarNo FALSE "" ""

        # We sleep lesser of iProgressSleepSeconds or iCurrTimerRemainingSec
        iCurrTimerRemainingSec=$(( iCurrTimerRemainingSec - iLastSleepSec))
        if [[ $iProgressSleepSeconds -gt $iCurrTimerRemainingSec ]]; then
            iLastSleepSec=$iCurrTimerRemainingSec
        else
            iLastSleepSec=$iProgressSleepSeconds
        fi

        tt=$((($(date +%s%N) - LastWakeMicroSeconds)/1000000))
        [[ $fLog == TRUE ]] && echo "Last lost time: $tt milliseconds" \
            >> ~/multi-timer.log
        TotalLostTime=$(( TotalLostTime + tt ))
        [[ $fLog == TRUE ]] && echo "Total Lost: $TotalLostTime milliseconds" \
            >> ~/multi-timer.log

        sleep $iLastSleepSec
        LastWakeMicroSeconds=$(date +%s%N)

    done

    # Currently removing Sysmonitor Indicator after current timer. Need to
    # modify to do it based on choice box for "Lock Screen".
    if [[ -f ~/.lock-screen-timer-remaining ]]; then
        # Remove Sysmonitor Indicator interface file.
        rm -f ~/.lock-screen-timer-remaining
    fi

    # Check for and display mssage and/or sound alarm
    EndMessageAndAlarm $fEndTimerMessage $fEndTimerAlarm \
                       "Timer: $sTimerAlias"

    # cbLockScreen="Never!Each timer end!Each set end!All sets end"  
    LockScreenCheck "Each timer end"
}

ZeroIndividualTimerProgressBars () {

    for ((i=1; i<=iActiveTimersCount; i++)); do
        echo "$i:0"
        echo "$i:#"
    done
}

###################################
#            MAINLINE             #
###################################

ReadConfiguration

if GetParameters ; then :
else
    # Escape or Cancel from yad notebook
    Cleanup
    exit 1
fi

InitTimers
if [[ $fAbend == TRUE ]]; then
    Cleanup
    exit 1
fi

SetupYadProgressBars
PrepareNewSet
LastWakeMicroSeconds=$(date +%s%N)

while [[ $fNewRun == TRUE ]]; do

    PrepareNewTimer
    while [[ $fNewTimer == TRUE ]]; do
        ProcessCurrTimer
        PrepareNewTimer
    done
    PrepareNewSet
    [[ $fNewRun == TRUE ]] && ZeroIndividualTimerProgressBars
    [[ $fLog == TRUE ]] && echo "Set Lost Time: $TotalLostTime milliseconds" \
        >> ~/multi-timer.log  # For some reason value is zero?

done | "${aYadProgressBars[@]}"

LockScreenCheck "All sets end"

# TO-DO why is $TotalLostTime zero below?
[[ $fLog == TRUE ]] && echo "All sets lost time: $TotalLostTime milliseconds" \
    >> ~/multi-timer.log

Cleanup

exit 0

Интерфейс индикатора Sysmonitor

Вы можете обновить область индикатора системного лотка / области приложения с оставшимся временем вместе с «прядильной текстовой пиццей», как показано в GIF в верхнем листе перечисления.

Чтобы установить индикатор Sysmonitor, см. этот Q & amp; A: multi-timer configuration.png [!d33]

4
ответ дан 8 June 2018 в 14:01
  • 1
    Но мне нужно установить секунды, а не минуты, невозможно с помощью таймера блокировки экрана? – Scorpion 23 May 2018 в 14:44
  • 2
    Секунды могут быть изменены на минуты с некоторыми незначительными изменениями. Я ухожу на работу, но сегодня я посмотрю. – WinEunuuchs2Unix 23 May 2018 в 14:46
  • 3
    Выглядит хорошо до сих пор. Следите за хорошую работу ! – Sergiy Kolodyazhnyy 28 May 2018 в 23:54
  • 4
    Впечатляющая работа. +1ед – Sergiy Kolodyazhnyy 1 June 2018 в 05:06
  • 5
    Дело не в том, что мне нужен мультитимер, у меня достаточно одного с утра, и я бы не хотел его использовать: D ... Но это заслуживает другого +1. И спасибо, что сообщили нам о яде. Я знал зенит, но у него есть уродливое предупреждающее сообщение в оболочке, когда вы его запускаете. Я обязательно попробую с яд в следующий раз. – kcdtv 1 June 2018 в 05:15

multi-timer bash script

Скрипт multi-timer bash работает в версиях Ubuntu 14.04, 16.04 и 18.04. Он также работает в Windows 10 с установленным Ubuntu 16.04 Desktop.

Он имеет функции:

Сохраняет конфигурацию между режимами использования. В наборе последовательно выполняется до 19 таймеров. Индикатор выполнения для каждого таймера. Набор таймеров можно запускать несколько раз. Индикатор выполнения для набора. Индикатор выполнения для всех наборов. Необязательное приглашение начать каждый таймер и / или установить. Дополнительное всплывающее сообщение, когда каждый таймер и / или набор заканчиваются. Дополнительный сигнал тревоги, когда каждый таймер и / или набор заканчиваются. Дополнительный экран блокировки, когда каждый таймер ИЛИ установлен ИЛИ все наборы заканчиваются. Дополнительный интерфейс для индикатора Sysmonitor, поэтому Systray показывает обратный отсчет. Дополнительный закрытие индикатора выполнения, когда все таймеры завершаются.

Требуется пакет yad sudo apt install yad

Вкладка «Конфигурация ноутбука»

yad (Еще один диалог) имеет функцию, которая позволяет полям multi-timer

Y позволяет вам:

Сохраняет конфигурацию между использованием. определить, сколько раз запускать набор таймеров. До 19 таймеров последовательно запускаются в комплекте. опция блокировки экрана в конце каждого таймера, набора или всех наборов Полоса хода для каждого таймера.

Вкладка «Таймеры для ноутбуков»

Вкладка «Таймеры» позволяет:

определить, сколько раз запускать набор таймеров. Установите количество секунд или минут каждого таймера.

Отображение индикатора хода

Поскольку multi-timer подсчитывает индикаторы выполнения, используются для:

Установите количество секунд или минут каждого таймера. опция блокировки экрана в конце каждого таймера, установки или всех наборов всех наборов (если запускаются два или более набора)

multi-timer configuration.png [!d33]

Bash Script

Скопируйте и вставьте скрипт bash ниже в имя файла multi-timer. Я предлагаю каталог /home/<your_user_name>/bin/. Затем пометьте скрипт как исполняемый файл, используя:

chmod a+x /home/<your_user_name>/bin/multi-timer

Изменение количества таймеров

В строках с номерами 78, 79 и 80 вы увидите следующее:

# No. of timers default is 17 for 768 line screen and TMR_DURATION_NDX is 30 TMR_DURATION_NDX=30 # Set to 28 for 800x600 screen, 32 for 1920x1080 screen MAX_TIMERS=17 # Set to 15 for 800x600 screen, 19 for 1920x1080 screen

Несмотря на то, что поддерживается 19 таймеров, они могут помещаться только на экран 1920x1080. Около 17 (настройка по умолчанию) будет помещаться на среднем экране 1024x768. Если у вас есть Super VGA с разрешением 800x600, вы можете получить только от 13 до 15 таймеров.

Вы должны изменить значения на линиях 85 & amp; 86 в то же время:

Bash field name ----------- Values to assign --------- TMR_DURATION_NDX 23 24 25 26 27 28 29 30 31 32 MAX_TIMERS 10 11 12 13 14 15 16 17 18 19

Например, если вы хотите не более 12 таймеров, установите TMR_DURATION_NDX=25 и MAX_TIMERS=12.

После изменения индекса и максимума сохраните multi-timer. Если вы уже запустили программу, как только файл конфигурации может быть создан, его нужно будет удалить. Используйте эту команду для удаления старого файла конфигурации:

`rm ~/.multi-timer`

Обратите внимание, что ~/ является короткой вырезкой в ​​вашем домашнем каталоге, то есть /home/your_user_name/.

Код Bash для multi-timer

#!/bin/bash # NAME: multi-timer # DESC: Multiple timers countdown with alarm. # https://askubuntu.com/questions/1039357 # /a-timer-to-set-up-different-alarms-simultaneosly # DATE: May 31, 2018. Modified June 7, 2018. # UPDT: 2018-06-07 Add new index for check box: "automatically close # progress bar display when all Sets finish. Use: rm ~/.multi-timer # to delete configuration file before running update. # NOTE: Following conventions are used: # Functions must be defined above point where they are called. # Yad style TRUE/FALSE instead of Bash true/false convention. # Variables beginning with- s is string # - i is integer # - f is TRUE/FALSE # - a is array # - cb is combobox # Must have the yad package. command -v yad >/dev/null 2>&1 || { echo >&2 \ "yad package required but it is not installed. Aborting."; \ exit 99; } # Running under WSL (Windows Subsystem for Linux)? if grep -Fxq "Microsoft" /proc/version; then #if cat /proc/version | grep Microsoft; then fWindows10=true else fWindows10=false fi # On Skylake i7-6700HQ .467 seconds lost over 20 minutes incl writing to file. if [[ "$1" == "-l" ]] || [[ "$1" == "--log-lost-time" ]] ; then fLog=TRUE else fLog=FALSE fi KEY="12345" # Key for tying Notebook pages (tabs) together OIFS=$IFS; # Save current IFS (Input File Separator) IFS="|"; # Yad fields and Bash array indices separated by `|` aMulti=() # Main array for storing configuration # Temporary files for Notebook output res1=$(mktemp --tmpdir iface1.XXXXXXXX) # Notebook Configuraion Page (Tab 1) res2=$(mktemp --tmpdir iface2.XXXXXXXX) # Notebook Timers Page (Tab 2) Cleanup () { rm -f "$res1" "$res2" # Remove temporary files IFS=$OIFS; # Retore Input File Separator if [[ -f ~/.lock-screen-timer-remaining ]]; then # Remove Sysmonitor Indicator interface file. rm -f ~/.lock-screen-timer-remaining fi } # Comboboxes, constants and Index offsets cbTimeUnits="Seconds!Minutes" cbLockScreen="Never!Each timer end!Each set end!All sets end" TIME_UNIT_NDX=0 SET_COUNT_NDX=1 PROGRESS_INTERVAL_NDX=2 ALARM_FILENAME_NDX=3 LOCK_SCREEN_NDX=4 PROMPT_BEFORE_TIMER_NDX=5 END_TIMER_MESSAGE_NDX=6 END_TIMER_ALARM_NDX=7 PROMPT_BEFORE_SET_NDX=8 END_SET_MESSAGE_NDX=9 END_SET_ALARM_NDX=10 SYSMONITOR_INDICATOR_NDX=11 CLOSE_PROGRAM_AT_END_NDX=12 TMR_ALIAS_NDX=13 # No. of timers default is 17 for 768 line screen and TMR_DURATION_NDX is 30 TMR_DURATION_NDX=30 # Set to 28 for 800x600 screen, 32 for 1920x1080 screen MAX_TIMERS=17 # Set to 15 for 800x600 screen, 19 for 1920x1080 screen ReadConfiguration () { if [[ -s ~/.multi-timer ]]; then read -ra aMulti < ~/.multi-timer for (( i=0; i<MAX_TIMERS; i++ )); do aAlias[i]="${aMulti[ i+TMR_ALIAS_NDX ]}" aDuration[i]="${aMulti[ i+TMR_DURATION_NDX ]}" done # Set Combobox default with ^ prefix Str="${aMulti[TIME_UNIT_NDX]}" cbTimeUnits="${cbTimeUnits/$Str/\^$Str}" Str="${aMulti[LOCK_SCREEN_NDX]}" cbLockScreen="${cbLockScreen/$Str/\^$Str}" else # Create new file aMulti[TIME_UNIT_NDX]="Seconds" aMulti[SET_COUNT_NDX]=1 aMulti[PROGRESS_INTERVAL_NDX]=1 aMulti[ALARM_FILENAME_NDX]="/usr/share/sounds/freedesktop/stereo/complete.oga" aMulti[LOCK_SCREEN_NDX]="Never" aMulti[PROMPT_BEFORE_TIMER_NDX]="FALSE" aMulti[END_TIMER_MESSAGE_NDX]="FALSE" aMulti[END_TIMER_ALARM_NDX]="TRUE" aMulti[PROMPT_BEFORE_SET_NDX]="FALSE" aMulti[END_SET_MESSAGE_NDX]="FALSE" aMulti[END_SET_ALARM_NDX]="FALSE" aMulti[SYSMONITOR_INDICATOR_NDX]="FALSE" aMulti[CLOSE_PROGRAM_AT_END_NDX]="FALSE" aAlias=("Timer 1" "Timer 2" "Timer 3" "Timer 4" "Timer 5" \ "Timer 6" "Timer 7" "Timer 8" "Timer 9" "Timer 10" \ "Timer 11" "Timer 12" "Timer 13" "Timer 14" "Timer 15" \ "Timer 16" "Timer 17" "Timer 18" "Timer 19") aDuration=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) fi } BuildTimerPage () { aTimerPage=() for ((i=0; i<MAX_TIMERS; i++)); do b1=$(( i + 1 )) aTimerPage+=("--field=Timer $b1 Alias:") aTimerPage+=("${aAlias[i]}") done for ((i=0; i<MAX_TIMERS; i++)); do aTimerPage+=("--field=Duration::NUM") aTimerPage+=("${aDuration[i]}") done } GetParameters () { # configuration notebook page yad --plug=$KEY --tabnum=1 --form \ --field="Timer duration units::CB" "$cbTimeUnits" \ --field="Number of times to run set (all timers)::NUM" \ "${aMulti[SET_COUNT_NDX]}"!1..99!1!0 \ --field="Progress Bar update every x seconds::NUM" \ "${aMulti[PROGRESS_INTERVAL_NDX]}"!1..60!1!0 \ --field="Alarm sound filename:FL" "${aMulti[ALARM_FILENAME_NDX]}" \ --field="Lock screen::CB" "$cbLockScreen" \ --field="Ask to begin each timer:CHK" \ "${aMulti[PROMPT_BEFORE_TIMER_NDX]}" \ --field="Pop-up message when each timer ends:CHK" \ "${aMulti[END_TIMER_MESSAGE_NDX]}" \ --field="Sound alarm when each timer ends:CHK" \ "${aMulti[END_TIMER_ALARM_NDX]}" \ --field="Ask to begin each set (all timers):CHK" \ "${aMulti[PROMPT_BEFORE_SET_NDX]}" \ --field="Pop-up message when each set ends:CHK" \ "${aMulti[END_SET_MESSAGE_NDX]}" \ --field="Sound alarm when each set ends:CHK" \ "${aMulti[END_SET_ALARM_NDX]}" \ --field="Interface to Sysmonitor Indicator:CHK" \ "${aMulti[SYSMONITOR_INDICATOR_NDX]}" \ --field="Auto close progress bar display when all sets end:CHK" \ "${aMulti[CLOSE_PROGRAM_AT_END_NDX]}" > "$res1" & # timers notebook page BuildTimerPage yad --plug=$KEY --tabnum=2 --form --columns=2 \ "${aTimerPage[@]}" > "$res2" & # run main dialog # --image=gnome-calculator if yad --notebook --key=$KEY --tab="Configuration" --tab="Timers" \ --image=/usr/share/icons/gnome/48x48/status/appointment-soon.png \ --title="multi-timer setup" --auto-close \ --width=400 --image-on-top --text="Multiple Timer settings" then # When LC_NUMERIC=it_IT-UTF8 30 seconds can be `30,000000` or # `30.000000` which breaks bash tests for `-gt 0`. # Search and replace ".000000" or ",000000" to null sed -i 's/[,.]000000//g' "$res1" sed -i 's/[,.]000000//g' "$res2" # Save configuration truncate -s -1 "$res1" # Remove new line at EOF cat "$res1" > ~/.multi-timer truncate -s -2 "$res2" # Remove trailing "|" and new line at EOF cat "$res2" >> ~/.multi-timer # Get user changes into aAlias & aDuration ReadConfiguration return 0 else return 1 # Cancel click or Escape press fi } fNewRun=FALSE fNewTimer=FALSE iSetSaveSec=0 InitTimers () { if [[ "${aMulti[TIME_UNIT_NDX]}" == "Seconds" ]]; then fUnitsInSeconds=TRUE else fUnitsInSeconds=FALSE fi iActiveTimersCount=0 for ((i=0; i<MAX_TIMERS; i++)); do if [[ ${aDuration[i]} -gt 0 ]] ; then (( iActiveTimersCount++ )) iSetSaveSec=$(( iSetSaveSec + ${aDuration[i]} )) fi done # Progress Bars, 1 per timer + optional: set and/or set count iAllSetsSaveCount="${aMulti[SET_COUNT_NDX]}" iAllSetsRemainingCount=$iAllSetsSaveCount fSetProgressBar=FALSE # Summary progress bar when > 1 timer used iSetProgressBarNo=0 fAllSetsProgressBar=FALSE # Summary progress bar when > 1 run iAllSetsProgressBarNo=0 if [[ $iActiveTimersCount -eq 0 ]]; then # If active timers count = 0, error message & clear run count yad --title "mutli-timer error" --center --text \ "At least one non-zero timer required." --image=dialog-error \ --on-top --borders=20 --button=gtk-close:0 iAllSetsRemainingCount=0 # Set orderly exit via sibling function(s) iProgressBarCount=0 fAbend=TRUE else # Active timers count > 0 so calculate times fNewTimer=TRUE fNewRun=TRUE [[ $fUnitsInSeconds == FALSE ]] && \ iSetSaveSec=$(( iSetSaveSec * 60 )) iAllSetsSaveCountSec=$(( iSetSaveSec * iAllSetsRemainingCount )) iAllSetsElapsedSec=0 iProgressBarCount=$iActiveTimersCount if [[ $iActiveTimersCount -gt 1 ]]; then (( iProgressBarCount++ )) # Extra progress bar for Set fSetProgressBar=TRUE iSetProgressBarNo=$iProgressBarCount fi if [[ $iAllSetsRemainingCount -gt 1 ]]; then (( iProgressBarCount++ )) # Extra progress bar for Set Count fAllSetsProgressBar=TRUE iAllSetsProgressBarNo=$iProgressBarCount fi fi # Friendly variable names instead of Array entries iProgressSleepSeconds="${aMulti[PROGRESS_INTERVAL_NDX]}" sSoundFilename="${aMulti[ALARM_FILENAME_NDX]}" fPromptBeforeTimer="${aMulti[PROMPT_BEFORE_TIMER_NDX]}" fEndTimerMessage="${aMulti[END_TIMER_MESSAGE_NDX]}" fEndTimerAlarm="${aMulti[END_TIMER_ALARM_NDX]}" fPromptBeforeSetRun="${aMulti[PROMPT_BEFORE_SET_NDX]}" fEndSetMessage="${aMulti[END_SET_MESSAGE_NDX]}" fEndSetAlarm="${aMulti[END_SET_ALARM_NDX]}" fSysmonitorIndicator="${aMulti[SYSMONITOR_INDICATOR_NDX]}" fCloseProgramAtEnd="${aMulti[CLOSE_PROGRAM_AT_END_NDX]}" } # Optional lost time log file monitors program execution time for progress # bars [[ $fLog == TRUE ]] && echo "multi-timer lost time log" > ~/multi-timer.log PromptToStart () { # $1= Message key text # Dialog box to proceed with timer. yad --title "mutli-timer notification" --center --on-top \ --fontname="Serif bold italic 28" \ --text "Ready to start $1" \ --image=/usr/share/icons/gnome/48x48/status/appointment-soon.png \ --borders=20 --button=gtk-execute:0 LastWakeMicroSeconds=$(date +%s%N) # Eliminate time waiting for user } EndMessageAndAlarm () { # $1= fEndTimerMessage, $2= fEndTimerAlarm, $3= Message key text # Sound alarm when timer ends if [[ "$2" == TRUE ]]; then if [[ ! -f "$sSoundFilename" ]]; then notify-send --urgency=critical "multi-timer" \ --icon=/usr/share/icons/gnome/48x48/status/appointment-soon.png \ "Sound file not found: $sSoundFilename" elif [[ $fWindows10 == TRUE ]]; then powershell.exe -c '(New-Object Media.SoundPlayer "$sSoundFilename").PlaySync();' else paplay "$sSoundFilename" ; fi fi # Bubble message when timer ends if [[ "$1" == TRUE ]]; then notify-send --urgency=critical "multi-timer" \ --icon=/usr/share/icons/gnome/48x48/status/appointment-soon.png \ "$3 has ended." # Something bold to test. Set $3 has ended. into $phrase # /usr/bin/notify-send --urgency=critical --icon=clock -t 4000 \ # "<i>Time Now</i>" "<span color='#57dafd' font='26px'><i><b>$phrase</b></i></span>" >/dev/null 2>&1 fi } LockScreenCheck () { # $1=Run type being checked: # "Each timer end" / "Each set end" / "All sets end" [[ "$1" != "${aMulti[$LOCK_SCREEN_NDX]}" ]] && return 0 # When locking screen override & prompt to start next timer / run [[ "$1" == "Each timer end" ]] && fPromptBeforeTimer=TRUE [[ "$1" == "Each set end" ]] && fPromptBeforeSetRun=TRUE if [[ $fWindows10 == TRUE ]]; then # Call lock screen for Windows 10 rundll32.exe user32.dll,LockWorkStation else # Call screen saver lock for Unbuntu versions >= 14.04. dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock fi } iCurrTimerNo=0 iCurrTimerNdx=0 TotalLostTime=0 PrepareNewSet () { # Was a set just completed? if [[ $iAllSetsRemainingCount -ne $iAllSetsSaveCount ]]; then # Display mssage and/or sound alarm for set end EndMessageAndAlarm $fEndSetMessage $fEndSetAlarm \ "$sSetProgressText" # Check to lock screen LockScreenCheck "Each set end" fi if [[ $iAllSetsRemainingCount -eq 0 ]]; then # We are done. Force exit from all while loops. fNewRun=FALSE fNewTimer=FALSE else # Decrement remaining run count and start at first timer. (( iAllSetsRemainingCount-- )) iSetElapsedSec=0 fNewTimer=TRUE iCurrTimerNo=0 iCurrTimerNdx=0 iNextTimerNdx=0 iCurrSetNo=$(( iAllSetsSaveCount - iAllSetsRemainingCount )) sSetProgressText="Set $iCurrSetNo of $iAllSetsSaveCount" [[ $fPromptBeforeSetRun == TRUE ]] && \ PromptToStart "$sSetProgressText" fi } PrepareNewTimer () { iCurrTimerElapsedSec=0 if [[ $iCurrTimerNo -eq $iActiveTimersCount ]]; then # Last timer done. Force exit from inner while loop. fNewTimer=FALSE return 0 fi for ((i=iNextTimerNdx; i<MAX_TIMERS; i++ )); do if [[ ${aDuration[i]} -gt 0 ]]; then iCurrTimerNdx=$i (( iCurrTimerNo++ )) # Increment progress bar number iNextTimerNdx=$(( iCurrTimerNdx + 1 )) iCurrTimerSaveSec=${aDuration[i]} [[ $fUnitsInSeconds == FALSE ]] && \ iCurrTimerSaveSec=$(( iCurrTimerSaveSec * 60 )) iCurrTimerRemainingSec=$iCurrTimerSaveSec break fi done } # Next function could be embedded within InitTimers to save space # and code line count but this provides better readability IMO. SetupYadProgressBars () { aYadProgressBars=("yad" "--multi-progress" "--center") aYadProgressBars+=("--title=multi-timer progress") [[ $fCloseProgramAtEnd == TRUE ]] && aYadProgressBars+=("--auto-close") aYadProgressBars+=("--auto-kill" "--watch-bar$iProgressBarCount") for ((i=0; i<MAX_TIMERS; i++)); do if [[ ${aDuration[i]} -gt 0 ]] ; then b1=$(( i + 1 )) aYadProgressBars+=("--bar=Timer $b1 - ${aAlias[i]}:NORM") fi done if [[ $fSetProgressBar == TRUE ]]; then aYadProgressBars+=("--bar=Set:NORM") fi if [[ $fAllSetsProgressBar == TRUE ]]; then aYadProgressBars+=("--bar=All Sets:NORM") fi } DisplayProgressBar () { # Parameters # $1=Elapsed Time, $2=Total Time, $3=Bar Number, # $4=TRUE/FALSE if eligible to update Sysmonitor Indicator # $5=Sysmonitor Indicator text for interface file or null # $6=Progress Text Prefix, ie "Set 2 of 4: " or null iPercentage=$(( $1 * 100 / $2 )) echo "$3:$iPercentage" RemainingSec=$(( $2 - $1 )) h=$((RemainingSec/3600)) m=$(((RemainingSec%3600)/60)) s=$((RemainingSec%60)) TimeRemaining="" [[ $h -gt 0 ]] && TimeRemaining=$TimeRemaining" $h Hours" [[ $m -gt 0 ]] && TimeRemaining=$TimeRemaining" $m Minutes" [[ $s -gt 0 ]] && TimeRemaining=$TimeRemaining" $s Seconds" if [[ $TimeRemaining == "" ]]; then echo "$3:#$6Finished." else echo "$3:#$6$TimeRemaining remaining." fi if [[ $fSysmonitorIndicator == TRUE ]] && [[ $4 == TRUE ]]; then echo "$5: $TimeRemaining" > ~/.lock-screen-timer-remaining fi } ProcessCurrTimer () { sTimerAlias="${aAlias[iCurrTimerNdx]}" # Dialog box to proceed with timer. [[ $fPromptBeforeTimer == TRUE ]] && PromptToStart "$sTimerAlias" iLastSleepSec=0 [[ $fLog == TRUE ]] && echo Start timer: "${aAlias[iCurrTimerNdx]}" \ >> ~/multi-timer.log while [[ $iCurrTimerElapsedSec -lt $iCurrTimerSaveSec ]]; do iCurrTimerElapsedSec=$(( iCurrTimerElapsedSec + iLastSleepSec)) iSetElapsedSec=$(( iSetElapsedSec + iLastSleepSec)) iAllSetsElapsedSec=$(( iAllSetsElapsedSec + iLastSleepSec)) DisplayProgressBar $iCurrTimerElapsedSec $iCurrTimerSaveSec \ $iCurrTimerNo TRUE "${aAlias[iCurrTimerNdx]}" "" "" if [[ $fSetProgressBar == TRUE ]] ; then DisplayProgressBar $iSetElapsedSec $iSetSaveSec \ $iSetProgressBarNo FALSE "" "$sSetProgressText: " fi [[ $fAllSetsProgressBar == TRUE ]] && \ DisplayProgressBar $iAllSetsElapsedSec $iAllSetsSaveCountSec \ $iAllSetsProgressBarNo FALSE "" "" # We sleep lesser of iProgressSleepSeconds or iCurrTimerRemainingSec iCurrTimerRemainingSec=$(( iCurrTimerRemainingSec - iLastSleepSec)) if [[ $iProgressSleepSeconds -gt $iCurrTimerRemainingSec ]]; then iLastSleepSec=$iCurrTimerRemainingSec else iLastSleepSec=$iProgressSleepSeconds fi tt=$((($(date +%s%N) - LastWakeMicroSeconds)/1000000)) [[ $fLog == TRUE ]] && echo "Last lost time: $tt milliseconds" \ >> ~/multi-timer.log TotalLostTime=$(( TotalLostTime + tt )) [[ $fLog == TRUE ]] && echo "Total Lost: $TotalLostTime milliseconds" \ >> ~/multi-timer.log sleep $iLastSleepSec LastWakeMicroSeconds=$(date +%s%N) done # Currently removing Sysmonitor Indicator after current timer. Need to # modify to do it based on choice box for "Lock Screen". if [[ -f ~/.lock-screen-timer-remaining ]]; then # Remove Sysmonitor Indicator interface file. rm -f ~/.lock-screen-timer-remaining fi # Check for and display mssage and/or sound alarm EndMessageAndAlarm $fEndTimerMessage $fEndTimerAlarm \ "Timer: $sTimerAlias" # cbLockScreen="Never!Each timer end!Each set end!All sets end" LockScreenCheck "Each timer end" } ZeroIndividualTimerProgressBars () { for ((i=1; i<=iActiveTimersCount; i++)); do echo "$i:0" echo "$i:#" done } ################################### # MAINLINE # ################################### ReadConfiguration if GetParameters ; then : else # Escape or Cancel from yad notebook Cleanup exit 1 fi InitTimers if [[ $fAbend == TRUE ]]; then Cleanup exit 1 fi SetupYadProgressBars PrepareNewSet LastWakeMicroSeconds=$(date +%s%N) while [[ $fNewRun == TRUE ]]; do PrepareNewTimer while [[ $fNewTimer == TRUE ]]; do ProcessCurrTimer PrepareNewTimer done PrepareNewSet [[ $fNewRun == TRUE ]] && ZeroIndividualTimerProgressBars [[ $fLog == TRUE ]] && echo "Set Lost Time: $TotalLostTime milliseconds" \ >> ~/multi-timer.log # For some reason value is zero? done | "${aYadProgressBars[@]}" LockScreenCheck "All sets end" # TO-DO why is $TotalLostTime zero below? [[ $fLog == TRUE ]] && echo "All sets lost time: $TotalLostTime milliseconds" \ >> ~/multi-timer.log Cleanup exit 0

Интерфейс индикатора Sysmonitor

Вы можете обновить область индикатора системного лотка / области приложения с оставшимся временем вместе с «прядильной текстовой пиццей», как показано в GIF в верхнем листе перечисления.

Чтобы установить индикатор Sysmonitor, см. этот Q & amp; A: multi-timer configuration.png [!d33]

4
ответ дан 17 July 2018 в 13:39

multi-timer bash script

Скрипт multi-timer bash работает в версиях Ubuntu 14.04, 16.04 и 18.04. Он также работает в Windows 10 с установленным Ubuntu 16.04 Desktop.

Он имеет функции:

Сохраняет конфигурацию между режимами использования. В наборе последовательно выполняется до 19 таймеров. Индикатор выполнения для каждого таймера. Набор таймеров можно запускать несколько раз. Индикатор выполнения для набора. Индикатор выполнения для всех наборов. Необязательное приглашение начать каждый таймер и / или установить. Дополнительное всплывающее сообщение, когда каждый таймер и / или набор заканчиваются. Дополнительный сигнал тревоги, когда каждый таймер и / или набор заканчиваются. Дополнительный экран блокировки, когда каждый таймер ИЛИ установлен ИЛИ все наборы заканчиваются. Дополнительный интерфейс для индикатора Sysmonitor, поэтому Systray показывает обратный отсчет. Дополнительный закрытие индикатора выполнения, когда все таймеры завершаются.

Требуется пакет yad sudo apt install yad

Вкладка «Конфигурация ноутбука»

yad (Еще один диалог) имеет функцию, которая позволяет полям multi-timer

Y позволяет вам:

Сохраняет конфигурацию между использованием. определить, сколько раз запускать набор таймеров. До 19 таймеров последовательно запускаются в комплекте. опция блокировки экрана в конце каждого таймера, набора или всех наборов Полоса хода для каждого таймера.

Вкладка «Таймеры для ноутбуков»

Вкладка «Таймеры» позволяет:

определить, сколько раз запускать набор таймеров. Установите количество секунд или минут каждого таймера.

Отображение индикатора хода

Поскольку multi-timer подсчитывает индикаторы выполнения, используются для:

Установите количество секунд или минут каждого таймера. опция блокировки экрана в конце каждого таймера, установки или всех наборов всех наборов (если запускаются два или более набора)

multi-timer configuration.png [!d33]

Bash Script

Скопируйте и вставьте скрипт bash ниже в имя файла multi-timer. Я предлагаю каталог /home/<your_user_name>/bin/. Затем пометьте скрипт как исполняемый файл, используя:

chmod a+x /home/<your_user_name>/bin/multi-timer

Изменение количества таймеров

В строках с номерами 78, 79 и 80 вы увидите следующее:

# No. of timers default is 17 for 768 line screen and TMR_DURATION_NDX is 30 TMR_DURATION_NDX=30 # Set to 28 for 800x600 screen, 32 for 1920x1080 screen MAX_TIMERS=17 # Set to 15 for 800x600 screen, 19 for 1920x1080 screen

Несмотря на то, что поддерживается 19 таймеров, они могут помещаться только на экран 1920x1080. Около 17 (настройка по умолчанию) будет помещаться на среднем экране 1024x768. Если у вас есть Super VGA с разрешением 800x600, вы можете получить только от 13 до 15 таймеров.

Вы должны изменить значения на линиях 85 & amp; 86 в то же время:

Bash field name ----------- Values to assign --------- TMR_DURATION_NDX 23 24 25 26 27 28 29 30 31 32 MAX_TIMERS 10 11 12 13 14 15 16 17 18 19

Например, если вы хотите не более 12 таймеров, установите TMR_DURATION_NDX=25 и MAX_TIMERS=12.

После изменения индекса и максимума сохраните multi-timer. Если вы уже запустили программу, как только файл конфигурации может быть создан, его нужно будет удалить. Используйте эту команду для удаления старого файла конфигурации:

`rm ~/.multi-timer`

Обратите внимание, что ~/ является короткой вырезкой в ​​вашем домашнем каталоге, то есть /home/your_user_name/.

Код Bash для multi-timer

#!/bin/bash # NAME: multi-timer # DESC: Multiple timers countdown with alarm. # https://askubuntu.com/questions/1039357 # /a-timer-to-set-up-different-alarms-simultaneosly # DATE: May 31, 2018. Modified June 7, 2018. # UPDT: 2018-06-07 Add new index for check box: "automatically close # progress bar display when all Sets finish. Use: rm ~/.multi-timer # to delete configuration file before running update. # NOTE: Following conventions are used: # Functions must be defined above point where they are called. # Yad style TRUE/FALSE instead of Bash true/false convention. # Variables beginning with- s is string # - i is integer # - f is TRUE/FALSE # - a is array # - cb is combobox # Must have the yad package. command -v yad >/dev/null 2>&1 || { echo >&2 \ "yad package required but it is not installed. Aborting."; \ exit 99; } # Running under WSL (Windows Subsystem for Linux)? if grep -Fxq "Microsoft" /proc/version; then #if cat /proc/version | grep Microsoft; then fWindows10=true else fWindows10=false fi # On Skylake i7-6700HQ .467 seconds lost over 20 minutes incl writing to file. if [[ "$1" == "-l" ]] || [[ "$1" == "--log-lost-time" ]] ; then fLog=TRUE else fLog=FALSE fi KEY="12345" # Key for tying Notebook pages (tabs) together OIFS=$IFS; # Save current IFS (Input File Separator) IFS="|"; # Yad fields and Bash array indices separated by `|` aMulti=() # Main array for storing configuration # Temporary files for Notebook output res1=$(mktemp --tmpdir iface1.XXXXXXXX) # Notebook Configuraion Page (Tab 1) res2=$(mktemp --tmpdir iface2.XXXXXXXX) # Notebook Timers Page (Tab 2) Cleanup () { rm -f "$res1" "$res2" # Remove temporary files IFS=$OIFS; # Retore Input File Separator if [[ -f ~/.lock-screen-timer-remaining ]]; then # Remove Sysmonitor Indicator interface file. rm -f ~/.lock-screen-timer-remaining fi } # Comboboxes, constants and Index offsets cbTimeUnits="Seconds!Minutes" cbLockScreen="Never!Each timer end!Each set end!All sets end" TIME_UNIT_NDX=0 SET_COUNT_NDX=1 PROGRESS_INTERVAL_NDX=2 ALARM_FILENAME_NDX=3 LOCK_SCREEN_NDX=4 PROMPT_BEFORE_TIMER_NDX=5 END_TIMER_MESSAGE_NDX=6 END_TIMER_ALARM_NDX=7 PROMPT_BEFORE_SET_NDX=8 END_SET_MESSAGE_NDX=9 END_SET_ALARM_NDX=10 SYSMONITOR_INDICATOR_NDX=11 CLOSE_PROGRAM_AT_END_NDX=12 TMR_ALIAS_NDX=13 # No. of timers default is 17 for 768 line screen and TMR_DURATION_NDX is 30 TMR_DURATION_NDX=30 # Set to 28 for 800x600 screen, 32 for 1920x1080 screen MAX_TIMERS=17 # Set to 15 for 800x600 screen, 19 for 1920x1080 screen ReadConfiguration () { if [[ -s ~/.multi-timer ]]; then read -ra aMulti < ~/.multi-timer for (( i=0; i<MAX_TIMERS; i++ )); do aAlias[i]="${aMulti[ i+TMR_ALIAS_NDX ]}" aDuration[i]="${aMulti[ i+TMR_DURATION_NDX ]}" done # Set Combobox default with ^ prefix Str="${aMulti[TIME_UNIT_NDX]}" cbTimeUnits="${cbTimeUnits/$Str/\^$Str}" Str="${aMulti[LOCK_SCREEN_NDX]}" cbLockScreen="${cbLockScreen/$Str/\^$Str}" else # Create new file aMulti[TIME_UNIT_NDX]="Seconds" aMulti[SET_COUNT_NDX]=1 aMulti[PROGRESS_INTERVAL_NDX]=1 aMulti[ALARM_FILENAME_NDX]="/usr/share/sounds/freedesktop/stereo/complete.oga" aMulti[LOCK_SCREEN_NDX]="Never" aMulti[PROMPT_BEFORE_TIMER_NDX]="FALSE" aMulti[END_TIMER_MESSAGE_NDX]="FALSE" aMulti[END_TIMER_ALARM_NDX]="TRUE" aMulti[PROMPT_BEFORE_SET_NDX]="FALSE" aMulti[END_SET_MESSAGE_NDX]="FALSE" aMulti[END_SET_ALARM_NDX]="FALSE" aMulti[SYSMONITOR_INDICATOR_NDX]="FALSE" aMulti[CLOSE_PROGRAM_AT_END_NDX]="FALSE" aAlias=("Timer 1" "Timer 2" "Timer 3" "Timer 4" "Timer 5" \ "Timer 6" "Timer 7" "Timer 8" "Timer 9" "Timer 10" \ "Timer 11" "Timer 12" "Timer 13" "Timer 14" "Timer 15" \ "Timer 16" "Timer 17" "Timer 18" "Timer 19") aDuration=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) fi } BuildTimerPage () { aTimerPage=() for ((i=0; i<MAX_TIMERS; i++)); do b1=$(( i + 1 )) aTimerPage+=("--field=Timer $b1 Alias:") aTimerPage+=("${aAlias[i]}") done for ((i=0; i<MAX_TIMERS; i++)); do aTimerPage+=("--field=Duration::NUM") aTimerPage+=("${aDuration[i]}") done } GetParameters () { # configuration notebook page yad --plug=$KEY --tabnum=1 --form \ --field="Timer duration units::CB" "$cbTimeUnits" \ --field="Number of times to run set (all timers)::NUM" \ "${aMulti[SET_COUNT_NDX]}"!1..99!1!0 \ --field="Progress Bar update every x seconds::NUM" \ "${aMulti[PROGRESS_INTERVAL_NDX]}"!1..60!1!0 \ --field="Alarm sound filename:FL" "${aMulti[ALARM_FILENAME_NDX]}" \ --field="Lock screen::CB" "$cbLockScreen" \ --field="Ask to begin each timer:CHK" \ "${aMulti[PROMPT_BEFORE_TIMER_NDX]}" \ --field="Pop-up message when each timer ends:CHK" \ "${aMulti[END_TIMER_MESSAGE_NDX]}" \ --field="Sound alarm when each timer ends:CHK" \ "${aMulti[END_TIMER_ALARM_NDX]}" \ --field="Ask to begin each set (all timers):CHK" \ "${aMulti[PROMPT_BEFORE_SET_NDX]}" \ --field="Pop-up message when each set ends:CHK" \ "${aMulti[END_SET_MESSAGE_NDX]}" \ --field="Sound alarm when each set ends:CHK" \ "${aMulti[END_SET_ALARM_NDX]}" \ --field="Interface to Sysmonitor Indicator:CHK" \ "${aMulti[SYSMONITOR_INDICATOR_NDX]}" \ --field="Auto close progress bar display when all sets end:CHK" \ "${aMulti[CLOSE_PROGRAM_AT_END_NDX]}" > "$res1" & # timers notebook page BuildTimerPage yad --plug=$KEY --tabnum=2 --form --columns=2 \ "${aTimerPage[@]}" > "$res2" & # run main dialog # --image=gnome-calculator if yad --notebook --key=$KEY --tab="Configuration" --tab="Timers" \ --image=/usr/share/icons/gnome/48x48/status/appointment-soon.png \ --title="multi-timer setup" --auto-close \ --width=400 --image-on-top --text="Multiple Timer settings" then # When LC_NUMERIC=it_IT-UTF8 30 seconds can be `30,000000` or # `30.000000` which breaks bash tests for `-gt 0`. # Search and replace ".000000" or ",000000" to null sed -i 's/[,.]000000//g' "$res1" sed -i 's/[,.]000000//g' "$res2" # Save configuration truncate -s -1 "$res1" # Remove new line at EOF cat "$res1" > ~/.multi-timer truncate -s -2 "$res2" # Remove trailing "|" and new line at EOF cat "$res2" >> ~/.multi-timer # Get user changes into aAlias & aDuration ReadConfiguration return 0 else return 1 # Cancel click or Escape press fi } fNewRun=FALSE fNewTimer=FALSE iSetSaveSec=0 InitTimers () { if [[ "${aMulti[TIME_UNIT_NDX]}" == "Seconds" ]]; then fUnitsInSeconds=TRUE else fUnitsInSeconds=FALSE fi iActiveTimersCount=0 for ((i=0; i<MAX_TIMERS; i++)); do if [[ ${aDuration[i]} -gt 0 ]] ; then (( iActiveTimersCount++ )) iSetSaveSec=$(( iSetSaveSec + ${aDuration[i]} )) fi done # Progress Bars, 1 per timer + optional: set and/or set count iAllSetsSaveCount="${aMulti[SET_COUNT_NDX]}" iAllSetsRemainingCount=$iAllSetsSaveCount fSetProgressBar=FALSE # Summary progress bar when > 1 timer used iSetProgressBarNo=0 fAllSetsProgressBar=FALSE # Summary progress bar when > 1 run iAllSetsProgressBarNo=0 if [[ $iActiveTimersCount -eq 0 ]]; then # If active timers count = 0, error message & clear run count yad --title "mutli-timer error" --center --text \ "At least one non-zero timer required." --image=dialog-error \ --on-top --borders=20 --button=gtk-close:0 iAllSetsRemainingCount=0 # Set orderly exit via sibling function(s) iProgressBarCount=0 fAbend=TRUE else # Active timers count > 0 so calculate times fNewTimer=TRUE fNewRun=TRUE [[ $fUnitsInSeconds == FALSE ]] && \ iSetSaveSec=$(( iSetSaveSec * 60 )) iAllSetsSaveCountSec=$(( iSetSaveSec * iAllSetsRemainingCount )) iAllSetsElapsedSec=0 iProgressBarCount=$iActiveTimersCount if [[ $iActiveTimersCount -gt 1 ]]; then (( iProgressBarCount++ )) # Extra progress bar for Set fSetProgressBar=TRUE iSetProgressBarNo=$iProgressBarCount fi if [[ $iAllSetsRemainingCount -gt 1 ]]; then (( iProgressBarCount++ )) # Extra progress bar for Set Count fAllSetsProgressBar=TRUE iAllSetsProgressBarNo=$iProgressBarCount fi fi # Friendly variable names instead of Array entries iProgressSleepSeconds="${aMulti[PROGRESS_INTERVAL_NDX]}" sSoundFilename="${aMulti[ALARM_FILENAME_NDX]}" fPromptBeforeTimer="${aMulti[PROMPT_BEFORE_TIMER_NDX]}" fEndTimerMessage="${aMulti[END_TIMER_MESSAGE_NDX]}" fEndTimerAlarm="${aMulti[END_TIMER_ALARM_NDX]}" fPromptBeforeSetRun="${aMulti[PROMPT_BEFORE_SET_NDX]}" fEndSetMessage="${aMulti[END_SET_MESSAGE_NDX]}" fEndSetAlarm="${aMulti[END_SET_ALARM_NDX]}" fSysmonitorIndicator="${aMulti[SYSMONITOR_INDICATOR_NDX]}" fCloseProgramAtEnd="${aMulti[CLOSE_PROGRAM_AT_END_NDX]}" } # Optional lost time log file monitors program execution time for progress # bars [[ $fLog == TRUE ]] && echo "multi-timer lost time log" > ~/multi-timer.log PromptToStart () { # $1= Message key text # Dialog box to proceed with timer. yad --title "mutli-timer notification" --center --on-top \ --fontname="Serif bold italic 28" \ --text "Ready to start $1" \ --image=/usr/share/icons/gnome/48x48/status/appointment-soon.png \ --borders=20 --button=gtk-execute:0 LastWakeMicroSeconds=$(date +%s%N) # Eliminate time waiting for user } EndMessageAndAlarm () { # $1= fEndTimerMessage, $2= fEndTimerAlarm, $3= Message key text # Sound alarm when timer ends if [[ "$2" == TRUE ]]; then if [[ ! -f "$sSoundFilename" ]]; then notify-send --urgency=critical "multi-timer" \ --icon=/usr/share/icons/gnome/48x48/status/appointment-soon.png \ "Sound file not found: $sSoundFilename" elif [[ $fWindows10 == TRUE ]]; then powershell.exe -c '(New-Object Media.SoundPlayer "$sSoundFilename").PlaySync();' else paplay "$sSoundFilename" ; fi fi # Bubble message when timer ends if [[ "$1" == TRUE ]]; then notify-send --urgency=critical "multi-timer" \ --icon=/usr/share/icons/gnome/48x48/status/appointment-soon.png \ "$3 has ended." # Something bold to test. Set $3 has ended. into $phrase # /usr/bin/notify-send --urgency=critical --icon=clock -t 4000 \ # "<i>Time Now</i>" "<span color='#57dafd' font='26px'><i><b>$phrase</b></i></span>" >/dev/null 2>&1 fi } LockScreenCheck () { # $1=Run type being checked: # "Each timer end" / "Each set end" / "All sets end" [[ "$1" != "${aMulti[$LOCK_SCREEN_NDX]}" ]] && return 0 # When locking screen override & prompt to start next timer / run [[ "$1" == "Each timer end" ]] && fPromptBeforeTimer=TRUE [[ "$1" == "Each set end" ]] && fPromptBeforeSetRun=TRUE if [[ $fWindows10 == TRUE ]]; then # Call lock screen for Windows 10 rundll32.exe user32.dll,LockWorkStation else # Call screen saver lock for Unbuntu versions >= 14.04. dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock fi } iCurrTimerNo=0 iCurrTimerNdx=0 TotalLostTime=0 PrepareNewSet () { # Was a set just completed? if [[ $iAllSetsRemainingCount -ne $iAllSetsSaveCount ]]; then # Display mssage and/or sound alarm for set end EndMessageAndAlarm $fEndSetMessage $fEndSetAlarm \ "$sSetProgressText" # Check to lock screen LockScreenCheck "Each set end" fi if [[ $iAllSetsRemainingCount -eq 0 ]]; then # We are done. Force exit from all while loops. fNewRun=FALSE fNewTimer=FALSE else # Decrement remaining run count and start at first timer. (( iAllSetsRemainingCount-- )) iSetElapsedSec=0 fNewTimer=TRUE iCurrTimerNo=0 iCurrTimerNdx=0 iNextTimerNdx=0 iCurrSetNo=$(( iAllSetsSaveCount - iAllSetsRemainingCount )) sSetProgressText="Set $iCurrSetNo of $iAllSetsSaveCount" [[ $fPromptBeforeSetRun == TRUE ]] && \ PromptToStart "$sSetProgressText" fi } PrepareNewTimer () { iCurrTimerElapsedSec=0 if [[ $iCurrTimerNo -eq $iActiveTimersCount ]]; then # Last timer done. Force exit from inner while loop. fNewTimer=FALSE return 0 fi for ((i=iNextTimerNdx; i<MAX_TIMERS; i++ )); do if [[ ${aDuration[i]} -gt 0 ]]; then iCurrTimerNdx=$i (( iCurrTimerNo++ )) # Increment progress bar number iNextTimerNdx=$(( iCurrTimerNdx + 1 )) iCurrTimerSaveSec=${aDuration[i]} [[ $fUnitsInSeconds == FALSE ]] && \ iCurrTimerSaveSec=$(( iCurrTimerSaveSec * 60 )) iCurrTimerRemainingSec=$iCurrTimerSaveSec break fi done } # Next function could be embedded within InitTimers to save space # and code line count but this provides better readability IMO. SetupYadProgressBars () { aYadProgressBars=("yad" "--multi-progress" "--center") aYadProgressBars+=("--title=multi-timer progress") [[ $fCloseProgramAtEnd == TRUE ]] && aYadProgressBars+=("--auto-close") aYadProgressBars+=("--auto-kill" "--watch-bar$iProgressBarCount") for ((i=0; i<MAX_TIMERS; i++)); do if [[ ${aDuration[i]} -gt 0 ]] ; then b1=$(( i + 1 )) aYadProgressBars+=("--bar=Timer $b1 - ${aAlias[i]}:NORM") fi done if [[ $fSetProgressBar == TRUE ]]; then aYadProgressBars+=("--bar=Set:NORM") fi if [[ $fAllSetsProgressBar == TRUE ]]; then aYadProgressBars+=("--bar=All Sets:NORM") fi } DisplayProgressBar () { # Parameters # $1=Elapsed Time, $2=Total Time, $3=Bar Number, # $4=TRUE/FALSE if eligible to update Sysmonitor Indicator # $5=Sysmonitor Indicator text for interface file or null # $6=Progress Text Prefix, ie "Set 2 of 4: " or null iPercentage=$(( $1 * 100 / $2 )) echo "$3:$iPercentage" RemainingSec=$(( $2 - $1 )) h=$((RemainingSec/3600)) m=$(((RemainingSec%3600)/60)) s=$((RemainingSec%60)) TimeRemaining="" [[ $h -gt 0 ]] && TimeRemaining=$TimeRemaining" $h Hours" [[ $m -gt 0 ]] && TimeRemaining=$TimeRemaining" $m Minutes" [[ $s -gt 0 ]] && TimeRemaining=$TimeRemaining" $s Seconds" if [[ $TimeRemaining == "" ]]; then echo "$3:#$6Finished." else echo "$3:#$6$TimeRemaining remaining." fi if [[ $fSysmonitorIndicator == TRUE ]] && [[ $4 == TRUE ]]; then echo "$5: $TimeRemaining" > ~/.lock-screen-timer-remaining fi } ProcessCurrTimer () { sTimerAlias="${aAlias[iCurrTimerNdx]}" # Dialog box to proceed with timer. [[ $fPromptBeforeTimer == TRUE ]] && PromptToStart "$sTimerAlias" iLastSleepSec=0 [[ $fLog == TRUE ]] && echo Start timer: "${aAlias[iCurrTimerNdx]}" \ >> ~/multi-timer.log while [[ $iCurrTimerElapsedSec -lt $iCurrTimerSaveSec ]]; do iCurrTimerElapsedSec=$(( iCurrTimerElapsedSec + iLastSleepSec)) iSetElapsedSec=$(( iSetElapsedSec + iLastSleepSec)) iAllSetsElapsedSec=$(( iAllSetsElapsedSec + iLastSleepSec)) DisplayProgressBar $iCurrTimerElapsedSec $iCurrTimerSaveSec \ $iCurrTimerNo TRUE "${aAlias[iCurrTimerNdx]}" "" "" if [[ $fSetProgressBar == TRUE ]] ; then DisplayProgressBar $iSetElapsedSec $iSetSaveSec \ $iSetProgressBarNo FALSE "" "$sSetProgressText: " fi [[ $fAllSetsProgressBar == TRUE ]] && \ DisplayProgressBar $iAllSetsElapsedSec $iAllSetsSaveCountSec \ $iAllSetsProgressBarNo FALSE "" "" # We sleep lesser of iProgressSleepSeconds or iCurrTimerRemainingSec iCurrTimerRemainingSec=$(( iCurrTimerRemainingSec - iLastSleepSec)) if [[ $iProgressSleepSeconds -gt $iCurrTimerRemainingSec ]]; then iLastSleepSec=$iCurrTimerRemainingSec else iLastSleepSec=$iProgressSleepSeconds fi tt=$((($(date +%s%N) - LastWakeMicroSeconds)/1000000)) [[ $fLog == TRUE ]] && echo "Last lost time: $tt milliseconds" \ >> ~/multi-timer.log TotalLostTime=$(( TotalLostTime + tt )) [[ $fLog == TRUE ]] && echo "Total Lost: $TotalLostTime milliseconds" \ >> ~/multi-timer.log sleep $iLastSleepSec LastWakeMicroSeconds=$(date +%s%N) done # Currently removing Sysmonitor Indicator after current timer. Need to # modify to do it based on choice box for "Lock Screen". if [[ -f ~/.lock-screen-timer-remaining ]]; then # Remove Sysmonitor Indicator interface file. rm -f ~/.lock-screen-timer-remaining fi # Check for and display mssage and/or sound alarm EndMessageAndAlarm $fEndTimerMessage $fEndTimerAlarm \ "Timer: $sTimerAlias" # cbLockScreen="Never!Each timer end!Each set end!All sets end" LockScreenCheck "Each timer end" } ZeroIndividualTimerProgressBars () { for ((i=1; i<=iActiveTimersCount; i++)); do echo "$i:0" echo "$i:#" done } ################################### # MAINLINE # ################################### ReadConfiguration if GetParameters ; then : else # Escape or Cancel from yad notebook Cleanup exit 1 fi InitTimers if [[ $fAbend == TRUE ]]; then Cleanup exit 1 fi SetupYadProgressBars PrepareNewSet LastWakeMicroSeconds=$(date +%s%N) while [[ $fNewRun == TRUE ]]; do PrepareNewTimer while [[ $fNewTimer == TRUE ]]; do ProcessCurrTimer PrepareNewTimer done PrepareNewSet [[ $fNewRun == TRUE ]] && ZeroIndividualTimerProgressBars [[ $fLog == TRUE ]] && echo "Set Lost Time: $TotalLostTime milliseconds" \ >> ~/multi-timer.log # For some reason value is zero? done | "${aYadProgressBars[@]}" LockScreenCheck "All sets end" # TO-DO why is $TotalLostTime zero below? [[ $fLog == TRUE ]] && echo "All sets lost time: $TotalLostTime milliseconds" \ >> ~/multi-timer.log Cleanup exit 0

Интерфейс индикатора Sysmonitor

Вы можете обновить область индикатора системного лотка / области приложения с оставшимся временем вместе с «прядильной текстовой пиццей», как показано в GIF в верхнем листе перечисления.

Чтобы установить индикатор Sysmonitor, см. этот Q & amp; A: multi-timer configuration.png [!d33]

4
ответ дан 20 July 2018 в 13:44

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

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