Перейдите на страницу веб-администрирования вашего шлюза и выполните поиск «переадресации портов» или «виртуального сервера»: шлюзу необходимо перенаправить пакеты на данный порт, например порт 22, на ваш внутренний IP-адрес.
Предположим, вы можете выбрать сервис из списка, ssh должен быть там. Затем вставьте внутренний IP-адрес вашего устройства в текстовое поле «IP-адрес сервера».
Для служб, не входящих в список, вы должны выбрать «Пользовательский сервер», я полагаю, что диалог изменится, чтобы вы могли ввести номер порта.
Для dyndns ваш шлюз может иметь поддержку (см. справку или документ шлюза), или вы можете использовать какое-то программное обеспечение на своем хосте для информирования о динамических изменениях внешнего IP-адреса.
Скрипт 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 подсчитывает индикаторы выполнения, используются для:
Установите количество секунд или минут каждого таймера. опция блокировки экрана в конце каждого таймера, установки или всех наборов всех наборов (если запускаются два или более набора)[!d33]
Скопируйте и вставьте скрипт 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/.
#!/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
Вы можете обновить область индикатора системного лотка / области приложения с оставшимся временем вместе с «прядильной текстовой пиццей», как показано в GIF в верхнем листе перечисления.
Чтобы установить индикатор Sysmonitor, см. этот Q & amp; A: [!d33]
Скрипт 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 подсчитывает индикаторы выполнения, используются для:
Установите количество секунд или минут каждого таймера. опция блокировки экрана в конце каждого таймера, установки или всех наборов всех наборов (если запускаются два или более набора)[!d33]
Скопируйте и вставьте скрипт 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/.
#!/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
Вы можете обновить область индикатора системного лотка / области приложения с оставшимся временем вместе с «прядильной текстовой пиццей», как показано в GIF в верхнем листе перечисления.
Чтобы установить индикатор Sysmonitor, см. этот Q & amp; A: [!d33]
Скрипт 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 подсчитывает индикаторы выполнения, используются для:
Установите количество секунд или минут каждого таймера. опция блокировки экрана в конце каждого таймера, установки или всех наборов всех наборов (если запускаются два или более набора)[!d33]
Скопируйте и вставьте скрипт 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/.
#!/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
Вы можете обновить область индикатора системного лотка / области приложения с оставшимся временем вместе с «прядильной текстовой пиццей», как показано в GIF в верхнем листе перечисления.
Чтобы установить индикатор Sysmonitor, см. этот Q & amp; A: [!d33]