How to run a bash sccript that uses gui functions every 15 minutes automatically?

So I have tried basically every single cron related google search result all to no avail. this is the script:

#!/bin/bash
todaysDateNumber=$(date '+%j')
sloc="$(dirname "$(readlink -f $0)")"
if ! grep "busy" "$sloc/$1prog_state.txt"; then
  echo "busy" >> "$sloc/$1prog_state.txt"
  wget "https://twitchtracker.com/$1" -O "$sloc/$1streamer.html"
  if grep 'LIVE</span>' "$sloc/$1streamer.html"; then
    doesExist=$(cat "$sloc/$1stream_state.txt" | grep -i -m 1 "$todaysDateNumber")
    if [ -z "${doesExist}" ]; then
      echo "stream found"
      if [ "$(notify-send "$1 is online!" "https://www.twitch.tv/$1/" -u CRITICAL -a "$1-detector" -A 'Open Stream' -A 'Nope')" -eq '0' ]; then
        xdg-open "https://www.twitch.tv/$1/"
      fi
      rm "$sloc/$1stream_state.txt"
      echo "$todaysDateNumber" >> "$sloc/$1stream_state.txt"
    fi
  else
    echo "No stream, exiting."
  fi
  rm "$sloc/$1streamer.html"
fi
rm "$sloc/$1prog_state.txt"

this it what SHOULD be happening (only behaves properly when run through a terminal window)
image

but this is whats happening (nothing)
image

here is a link to the stream in question that I am using to test this

I have tried setting the $DISPLAY variable to :1 and also setting XDG_RUNTIME_DIR=/run/user/$(id -u) in cron, nothing has worked.

so i fixed the notification problem but now xdg-open is not working
this is my crontab

DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"

*/1 10,11,12,13,14,15,16,17,18,19,20 * * * env DISPLAY=:1 bash /home/usr_40476/Projects/twitchOnline\?/twitchonline.sh zentreya > /dev/null 2>&1

cron doesnā€™t know anything about the display manager. You can try prefixing the command with DISPLAY=:0 and see if that helps, or possibly in the bash script itself, you could try setting the DISPLAY value to :0 and see if that helps.

so i got it working by doing this,

DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"

*/15 10,11,12,13,14,15,16,17,18,19,20 * * * env DISPLAY=:1 bash /home/usr_40476/Projects/twitchOnline\?/twitchonline.sh zentreya > /dev/null 2>&1

DBUS_SESSION_BUS_ADDRESS=ā€œunix:path=/run/user/1000/busā€
and env DISPLAY=:1

I did see something about xdg-open and cron not working well together, but I do have an idea. ASK THE USER WHICH PROGRAM TO USE OMG IMMA GENIUS AHHHH

I just lost my marbles, this has been befuddling me for days now. :rofl:

1 Like

Iā€™ve long said that computers do exactly what you tell them to. The trick to getting them to do what you want is to make sure that what you told it to do is what you wanted it to do. Often times, thatā€™s where the issue is.

In the case of cron, itā€™s intended to run background tasks, and it runs the tasks in that environment - not in the desktop environment. If another user is logged in, this probably wouldnā€™t work, because they wouldnā€™t be authorized to access the display.

BTW, display :0 is usually the default - :1 is usually a second display (not necessarily a second monitor, but a second Xorg instance).

soooo, what would I use instead? a systemd unit?

@40476 not sure why you donā€™t just run as a user systemd timer and serviceā€¦

Iā€™m a lazy bum and systemd units seem complicated even though they are probably dead simple?

basically i want the systemd timer to run every 15 minutes from 10:30 AM to 8:30 PM

If it were me, Iā€™d probably look to see if there was an event-driven way to do it rather than a polling way to do it.

Itā€™s likely there is some sort of a ā€˜twitch indicatorā€™ :wink: open source application that might have some ideas about how to do this with the twitch API rather than scraping an HTML page (which can prove very frustrating as things are updated on the page).

If the goal is to learn while doing it, thatā€™s one thing - if you just want a solution, thatā€™s something else.

mostly just trying to learn, but also need the functinality. primarily for my brother since the streamer i tune into while I am doing things goes on at the same time every as opposed to this discord meme person that he likes watching.

@40476

[Unit]
Description=40476 timer

[Timer]
OnCalendar=10:30,15:30,20:30,25:30
AccuracySec=1min
Persistent=true

[Install]
WantedBy=timers.target

So you would create a systemd service eg 40476.service for your script, then call the timer name the same eg 40476.timer and save both in ~/.config/systemd/user/ and as your user run systemctl --user enable --now 40476.timer

1 Like

for the sake of me learning, (I have only been on linux for about 1.7 years) could you explain how the values work?
because it looks like it is running every 5 minutes

this was the one I made from pulling together stuff off google

[Unit]
Description=Run every 15 minutes from 10:30 AM to 8:30 PM

[Timer]
OnCalendar=*-*-* 10-20:30/15

[Install]
WantedBy=timers.target

@40476 Have a read of man 7 systemd.time

Then there is systemd-analyze calendar your string for example;

systemd-analyze calendar "*-*-* 10:30,20:30/15"

Original form: *-*-* 10:30,20:30/15
Normalized form: *-*-* 10:20,30:30/15
    Next elapse: Thu 2024-05-16 10:20:30 CDT
       (in UTC): Thu 2024-05-16 15:20:30 UTC
       From now: 13h left

Context matters. Presumably you want to run your service in the user slice:

karl@3400g:~> systemctl --user status save-jalbum-settings.service
ā— save-jalbum-settings.service - Save jAlbum Project Files
     Loaded: loaded (/home/karl/.config/systemd/user/save-jalbum-settings.service; enabled; preset: disabled)
     Active: active (running) since Tue 2024-05-14 02:26:53 CEST; 2 days ago
   Main PID: 1703 (bash)
      Tasks: 2 (limit: 4915)
        CPU: 8.834s
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/save-jalbum-settings.service
             ā”œā”€1703 /bin/bash /home/karl/bin/save-jalbum-settings.sh
             ā””ā”€1916 sleep 60

Mai 14 02:26:53 3400g systemd[1693]: Started Save jAlbum Project Files.
karl@3400g:~> 
andrei@tumbleweed:~> systemd-analyze calendar "*-*-* 10-20:30/15"
Failed to parse calendar specification '*-*-* 10-20:30/15': Invalid argument
andrei@tumbleweed:~>

10-20 is not valid in time specification; see man systemd.time.

alrgiht, so I finally got it working, I will provide an update tomorrow, on how the script is working.

Working great! thanks for the help, I will post my solution in a about an hour (need to clean it up a little)

twitchonline.sh

#!/bin/bash

todaysDateNumber=$(date '+%j')
sloc="$(dirname "$(readlink -f $0)")"
doesExist=$(cat "$sloc/$1stream_state.txt" | grep -i -m 1 "$todaysDateNumber")
if [ -z "${doesExist}" ]; then
  if ! grep "busy" "$sloc/$1prog_state.txt"; then
    echo "busy" >> "$sloc/$1prog_state.txt"
    wget "https://twitchtracker.com/$1" -O "$sloc/$1streamer.html"
    if grep 'LIVE</span>' "$sloc/$1streamer.html"; then
        echo "stream found."
        if [ "$(notify-send "$1 is online!" "https://www.twitch.tv/$1/" -u CRITICAL -a "$1-detector" -A 'Open Stream' -A 'Nope')" -eq '0' ]; then
          xdg-open "https://www.twitch.tv/$1/"
        fi
        rm "$sloc/$1stream_state.txt"
        echo "$todaysDateNumber" >> "$sloc/$1stream_state.txt"
    else
      echo "No stream, exiting."
    fi
  else
    echo  "program already active, exiting."
  fi
fi
rm "$sloc/$1streamer.html" > /dev/null 2>&1
rm "$sloc/$1prog_state.txt" > /dev/null 2>&1

twitchonline_zentreya.timer

[Unit]
Description=Run every 15 minutes from 10:30 AM to 8:30 PM

[Timer]
OnCalendar=10:30
OnCalendar=10:45
OnCalendar=11:00
OnCalendar=11:15
OnCalendar=11:30
OnCalendar=11:45
OnCalendar=12:00
OnCalendar=12:15
OnCalendar=12:30
OnCalendar=12:45
OnCalendar=13:00
OnCalendar=13:15
OnCalendar=13:30
OnCalendar=13:45
OnCalendar=14:00
OnCalendar=14:15
OnCalendar=14:30
OnCalendar=14:45
OnCalendar=15:00
OnCalendar=15:15
OnCalendar=15:30
OnCalendar=15:45
OnCalendar=16:00
OnCalendar=16:15
OnCalendar=16:30
OnCalendar=16:45
OnCalendar=17:00
OnCalendar=17:15
OnCalendar=17:30
OnCalendar=17:45
OnCalendar=18:00
OnCalendar=18:15
OnCalendar=18:30
OnCalendar=18:45
OnCalendar=19:00
OnCalendar=19:15
OnCalendar=19:30
OnCalendar=19:45
OnCalendar=20:00
OnCalendar=20:15
AccuracySec=1min
Unit=twitchonline_zentreya.service

[Install]
WantedBy=timers.target

twitchonline_zentreya.service

[Unit]
Description="duh"

[Service]
Type=oneshot
ExecStart=/bin/bash /home/usr_40476/Projects/twitchOnline/twitchonline.sh zentreya

[Install]
WantedBy=twitchonline_zentreya.timer

Hi,

According to

grep --help| head -n4

The output looks something like:

Usage: grep [OPTION]... PATTERN [FILE]...
Search for PATTERN in each FILE.
Example: grep -i 'hello world' menu.h main.c