16

There are often times that I want my computer to do a single task, but not right now. For example, I could have it notify me in 30 minutes that it is time to leave work. Or maybe I want it to run a complicated test 2 hours from now when I'm sure most everyone else will be gone from the office.

I know I could create a cron job to run at a specific time of day, but that seems like a lot of work when all I want is something simple like "Run this script in 10 minutes", besides I'd have to figure out what time it will actually be X minutes/hours/days from now, and then delete the cron job once it finished.

Of course I could just write this script and run it in the background:

sleep X
do_task

But that just seems so clunky: I either need a new script for each task, or I need to write and maintain a script generic enough to do what I want, not to mention I have to figure out how many seconds are in the minutes, hours, or days I want.

Is there not an already established solution to this problem?

2
  • 7
    I'm guessing you've not run across at yet?
    – jw013
    May 3, 2012 at 0:09
  • this might seem very basic...but doesn't your system have any kind of calendar/todo list thing, with warnings? May 3, 2012 at 12:23

3 Answers 3

27

I use a simple script with at:

#!/bin/bash
# email reminder notes using at(1)...

read -p "Time of message? [HH:MM] " time
read -p "Date of message? [dd.mm.yy] " date
read -p "Message body? " message

at "$time" "$date" <<EOF
echo "$message" | mailx -s "REMINDER" [email protected]
EOF

You could just as easily pipe the $message to notify-send or dzen if you wanted a desktop notification instead of an email.

5
  • 9
    Can also use relative time (+ 2 days) and different formats (YYYY-MM-DD). Consult the manpage for more details.
    – Arcege
    May 3, 2012 at 0:30
  • Yes: us antipodeans prefer DD-MM-YY :)
    – jasonwryan
    May 3, 2012 at 4:01
  • I usually us at for quickie one off scripts. My favorite lazy way to schedule an at job is "now +5 minutes" which could also be hours or days.
    – George M
    May 3, 2012 at 20:47
  • 1
    +1 for script and for mentioning dzen and notify-send which I had not heard of.
    – Joe
    May 5, 2012 at 21:27
  • The dzen redirection isn't working for me. unix.stackexchange.com/q/38362/4143
    – Cory Klein
    May 10, 2012 at 22:22
6

The generic way to use at is

Write a script that does what you want to do. Use the full path for all external commands, log output to a proper log-file or mail it.

Test the script.

Activate it with at -f YOURSCRIPT -t MMDDhhmm

1

In 2023 you would probably want to accomplish this with systemd instead of at since many distributions now disable atd by default.

You could use systemctl as follows:

systemd-run --user --on-calendar=<iso time> <command> [arguments...]

For instance

systemd-run --user --on-calendar="2023-11-03 07:00" /usr/bin/aplay /home/user/chime.wav

This creates a transient timer that would be deleted after the execution of the command. If instead the argument of --on-calendar contains asterisks, e.g. --on-calendar="--* 07:00", this command will be executed daily.

To get a list of all configured timers use

systemctl --user list-timers

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .