LINUX.ORG.RU

Таймер-напоминалка простейший

 , ,


0

1

Набрал в поиске таймер линукс и он выдал , что таймер можно использовать с помощью systemd,cron , ну и конечно различными clock-ами.

Попробовал гномовский , но там столько зависимостей для моей оси,что не стал заморачиваться и написал простейший таймер.

Конечно можно сказать,что это ‘непрограммирование’,возможно,но работает))

if [ -z "$(which yad)" ]; then echo "Пакет 'yad' не установлен"; exit 0; fi; TIME_CHOOSE=$(yad --form --separator=" " --field=Дни:NUM --field=Часы:NUM  --field=Минуты:NUM --field=Секунды:NUM --field="Самозапуск:CHK" | awk -F ' ' '{print "sleep "$1"d "$2"h "$3"m "$4"s "}{print $5}'); if [ "$(echo "$TIME_CHOOSE" | grep 'FALSE')" ]; then  eval "$(echo "$TIME_CHOOSE" | head -1)" && yad --geometry "1500x850+100+50" --text-info  --title="Пора сделать разминку"  --timeout=2 --fontname="Serif bold italic 150" --fore=red  --back=black  --justify=center <<< $(echo -e "^|^ Пора \nсделать\n разминку") > /dev/null; else i=1; while true; do eval "$(echo "$TIME_CHOOSE" | head -1)" && yad --geometry "1500x850+100+50" --text-info  --title="Пора сделать разминку"  --timeout=2 --fontname="Serif bold italic 150" --fore=red  --back=black  --justify=center <<< $(echo -e "^|^ Пора \nсделать\n разминку"); i=$(($i + 1)); done; fi

Написал в одну строчку,чтобы удобнее было запустить в терминале и посмотреть. Правда одна зависимость есть - нужен yad || zenity.(можно заменить все yad на zenity)

Если поставить галочку, будет появлятся сообщение через установленное время автоматически.

–timeout=2 время показа баннера

–geometry «1500x850+100+50» размеры и расположение баннера

Останавливается как обычно ctrl+c.

Надеюсь поможет незасиживаться.

Развернутая версия

#!/bin/sh

if [ -z "$(which yad)" ]; then echo "Пакет 'yad' не установлен"; exit 0; fi

 TIME_CHOOSE=$(yad --form --separator=" " --field=Дни:NUM !0..60 \
  --field=Часы:NUM !0..23 \
  --field=Минуты:NUM !0..59 \
  --field=Секунды:NUM !0..59 \
  --field="Самозапуск:CHK" | awk -F ' ' '{print "sleep "$1"d "$2"h "$3"m "$4"s "}{print $5}')
  
   if [ "$(echo "$TIME_CHOOSE" | grep 'FALSE')" ]; then 
    eval "$(echo "$TIME_CHOOSE" | head -1)" && \
    yad --geometry "1500x850+100+50" \
    --text-info  \
    --title="Пора сделать разминку" \
     --timeout=2 \
     --fontname="Serif bold italic 150" \
      --fore=red \
       --back=black \
        --justify=center \
         --undecorated \
         --no-buttons \
         --skip-taskbar \
         --on-top <<< $(echo -e "^|^ Пора \nсделать\n разминку") > /dev/null
     else 
     i=1
      while true
     do
       eval "$(echo "$TIME_CHOOSE" | head -1)" && \
       yad --geometry "1500x850+100+50" \
       --text-info  \
       --title="Пора сделать разминку"  \
       --timeout=2 \
       --fontname="Serif bold italic 150" \
       --fore=red  \
       --back=black  \
       --justify=center \
       --undecorated \
       --skip-taskbar \
       --no-buttons \
       --on-top <<< $(echo -e "^|^ Пора \nсделать\n разминку")
        i=$(($i + 1))
     done 
          fi


Последнее исправление: nik120s (всего исправлений: 3)

Написал в одну строчку,чтобы удобнее было

Так делать не надо. Надо делать чтоб читаемо было. После однострочника на Perl вряд ли кто-то захочет запускать непонятный код с форума.

unDEFER ★★★★★
()

поможет незасиживаться

мне надо каждые полчаса за трансорматором ходить следить - в любой момент может загореться, на самом деле я не понимаю зачем ходить, ну пришел - посмотрел, а он через 3 минуты после этого загорелся и все эти хождения каждые пол часа псу под хвост, даже домой пообедать не свалить.

amd_amd ★★★★★
()
/* alarm.c (c) firk 2021, 2025 */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <math.h>

typedef unsigned int u;

static int write_all(int fd, unsigned char const *buf, size_t n) {
  ssize_t r;
  while(n) {
    r = write(fd, buf, n);
    if(r<0) { if(errno==EINTR) continue; return -1; }
    assert(r>0 && n>=(size_t)r);
    buf += r;
    n -= r;
  }
  return 0;
}

static int parse_u(char const *s, char const **ps, u *res) {
  unsigned char c;
  u r, t;
  if(!(c = *s)) return -1;
  c -= '0';
  if(c>9) return -1;
  r = c; s++;
  while(c=*s) {
    c -= '0';
    if(c>9) { if(ps) break; return -1; }
    t = r*10;
    if(t/10!=r) return -1;
    r = t+c;
    if(r<t) return -1;
    s++;
  }
  *res = r;
  if(ps) *ps = s;
  return 0;
}

static int parse_delay(char const *s, u *r) {
  u a1, a2, a3, t, res;
  res = 0;
  while(1) {
    if(parse_u(s, &s, &a1)<0) return -1;
    switch(*(s++)) {
    default: return -1;
    case 'S': case 's': if(*s) return -1;
    case 0:                               res+=a1; if(res<a1) return -1; *r = res; return 0;
    case 'D': case 'd': t = a1*86400; if(t/86400!=a1) return -1; res+=t; if(res<t) return -1; break;
    case 'H': case 'h': t = a1*3600; if(t/3600!=a1) return -1; res+=t; if(res<t) return -1; break;
    case 'M': case 'm': t = a1*60; if(t/60!=a1) return -1; res+=t; if(res<t) return -1; break;
    case ':': goto colon;
    }
    if(!*s) { *r = res; return 0; }
  }
colon:
  if(parse_u(s, &s, &a2)<0) return -1;
  switch(*(s++)) {
  default: return -1;
  case ':': break;
  case 0:
    t = a1*60; if(t/60!=a1) return -1; res+=t; if(res<t) return -1;
    res+=a2; if(res<a2) return -1; *r = res; return 0;
  }
  if(parse_u(s, &s, &a3)<0) return -1;
  if(*s) return -1;
  t = a1*3600; if(t/3600!=a1) return -1; res+=t; if(res<t) return -1;
  t = a2*60; if(t/60!=a2) return -1; res+=t; if(res<t) return -1;
  res+=a3; if(res<a3) return -1; *r = res; return 0;
}

static unsigned char data[11025];

int main(int argc, char **argv, char **envp) {
  char *args[6];
  pid_t r;
  int p[2], devnull;
  u delay;
  unsigned int i, value, freq, volume, mode;
  int sv;
  if(argc<2) delay = 0; else if(parse_delay(argv[1], &delay)<0) { fprintf(stderr, "bad delay, using 0\n"); delay = 0; }
  if(argc>=3) volume = strtoul(argv[2],NULL,0); else volume = 10;
  if(argc>=4) freq = strtoul(argv[3],NULL,0); else freq = 861;
  if(argc>=5 && !strcmp(argv[4],"sin")) mode = 1; else mode = 0;
  while(delay--) {
    sleep(1);
    printf("\rremaining: %02u:%02u:%02u", (unsigned)(delay/3600), (unsigned)((delay%3600)/60), (unsigned)(delay%60)); fflush(stdout);
  }
  printf("\r                   \r"); fflush(stdout);
  if((devnull=open("/dev/null",O_WRONLY))<0) { fprintf(stderr,"open(/dev/null) error %d (%s)\n",errno,strerror(errno)); return -1; }
  if(pipe(p)<0) { fprintf(stderr,"pipe() error %d (%s)\n",errno,strerror(errno)); return -1; }
  if((r=fork())<0) { fprintf(stderr,"fork() error %d (%s)\n",errno,strerror(errno)); return -1; }
  if(!r) {
    if(dup2(p[0],0)<0) { fprintf(stderr,"dup2(,0) error %d (%s)\n",errno,strerror(errno)); exit(-1); }
    if(dup2(2,p[0])<0) { fprintf(stderr,"dup2(2,) error %d (%s)\n",errno,strerror(errno)); exit(-1); }
    if(dup2(devnull,1)<0) { fprintf(stderr,"dup2(,1) error %d (%s)\n",errno,strerror(errno)); exit(-1); }
    if(dup2(devnull,2)<0) { fprintf(stderr,"dup2(,2) error %d (%s)\n",errno,strerror(errno)); exit(-1); }
    close(p[1]);
    args[0] = "/usr/bin/aplay";
    args[1] = "-f";
    args[2] = "U8";
    args[3] = "-r";
    args[4] = "22050";
    args[5] = NULL;
    execve(args[0], args, envp);
    dprintf(p[0],"failed to call player: execve() error %d (%s)\n",errno,strerror(errno));
    exit(-1);
  }
  close(p[0]);
  for(i=0; i<sizeof(data); i++) {
    if(!mode) {
      value = (i*freq*256/22050) & 255;
      if(volume<10) value /= (11-volume);
    } else {
      sv = (int)(sin(6.2832*freq*i/22050)*127);
      if(volume<10) sv /= (int)(11-volume);
      value = sv+128;
    }
    data[i] = value;
  }
  while(1) {
    if(write_all(p[1], data, sizeof(data))<0) {
      fprintf(stderr,"failed to send sound data\n");
      return -1;
    }
    sleep(1);
  }
  return 0;
}
firkax ★★★★★
()

Я себе похожее наговнякал, запускаю примерно так:

timer 5m ; alarm blabla

alarm тоже скрипт, там notify-send и mpv звук звонка. По сути красивый sleep, показывающий сколько там осталось.

import argparse
import re
import sys
from time import monotonic_ns, sleep


T_RE = re.compile(r'^(\d+)([wdhms])')
KMAP = {
    'w': 604800,
    'd': 86400,
    'h': 3600,
    'm': 60,
    's': 1,
}


def create_parser():
    p = argparse.ArgumentParser()
    p.add_argument('timespec', nargs='+', help=(
        'Example: 1d 5h 45m; '
        's: seconds; '
        'm: minutes; '
        'h: hours; '
        'd: days; '
        'w: weeks'
    ))
    return p


def error(msg, exitcode=1):
    print(msg, file=sys.stderr)
    exit(exitcode)


def parse_timespec(tsp):
    seconds = 0
    for part in tsp:
        part = part.lower().strip()
        while part:
            if (m := T_RE.match(part)) is None:
                error(f'Unrecognized part: {part}')
            n, unit = m.group(1), m.group(2)
            seconds += int(n) * KMAP[unit]
            part = part[m.end():].lstrip()
    return seconds


def _mod(ts, d):
    return ts % d, ts // d


def time_string(t, total):
    percent = 1000 - t * 1000 // total
    percent = f'{percent // 10:>02}.{percent % 10:>01}%'
    s, t = _mod(t, 60)
    m, t = _mod(t, 60)
    h, d = _mod(t, 24)
    r = ''
    if d == 1:
        r = '1 day '
    elif d > 1:
        r = f'{d} days '
    return r + f'{h:>02}:{m:>02}:{s:>02} {percent} '


def print_same_line(text):
    print('\x1B[2K\x0D' + text, end='')


def main(args):
    seconds = parse_timespec(args.timespec)
    try:
        until = monotonic_ns() + seconds * 1_000_000_000
        while (t := monotonic_ns()) <= until:
            print_same_line(time_string(
                (until - t) // 1_000_000_000,
                seconds))
            sleep(1)
        print_same_line('Timer went off')
        print()
    except KeyboardInterrupt:
        print_same_line('')
        error('Timer has been cancelled')


if __name__ == '__main__':
    main(create_parser().parse_args())
neumond
()
Последнее исправление: neumond (всего исправлений: 1)