Running a task at a specified time on a Mac

Unix computers have a simple command-line feature called “at” which lets you schedule a command, or a series of commands, to be run at a specific time.    For example, if you want to download a large file in the middle of the night, when there is less congestion on the network, you can easily do so.    Since the Apple Macintosh computer is based on BSD Unix, this feature is available on a Mac, though it is turned off by default.     I’ll use downloading a file as an example in what follows, but you can use this to run almost any command at a specified time.

As you might expect, everything here is done via the command line, which means you will have to run the Terminal app.   With the Finder it is in /Applications/Utilities, while using Launchpad you will find it in a folder called either “Other” or “Utilities”.

Starting atrun

The “at” service is provided by a Unix daemon called “atrun”, which is turned off by default on a Mac.   To turn it on you have to give the command1

 sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist

You will need to do this again if you reboot, though there is a way (see Reference 1) to turn it on permanently.

Simple Example

Let’s test the system first. The command is simply “at” followed by a time or date (or both). So if it’s currently 10:00 AM, then the commmand  “at 1002”  will run the command(s) in 2 minutes.   Once you give this command the terminal will wait for your input.  Enter as many Unix commands as you like, one per line.  I’ll just demonstrate with the “echo” command.  When you are done, press Control-D (the Unix end of data character, often written in examples as “^D”).  When you do so, you’ll get a line telling you the job number and date and time it will run. Here’s an example (the parts in red are what I typed):

thrain:myers> date
Thu Aug 16 10:00:45 EDT 2018
thrain:myers> at 1002
echo "Hello, World!"
^D
job 8 at Thu Aug 16 10:02:00 2018

The command “atq” will show you the contents of the queue of commands waiting to be run.

thrain:myers> atq
8       Thu Aug 16 10:02:00 2018

The job is queued to run at 10:02. When I check on it at 10:03 I find:

thrain:myers> date
Thu Aug 16 10:03:48 EDT 2018
thrain:myers> atq
thrain:myers>

The lack of output means there is nothing in the queue. Where did it go? The output is sent to you using the Unix mail system. It won’t go to your gmail account, but you can easily get it using the local Unix “mail” command:

thrain:myers> mail
Mail version 8.1 6/6/93.  Type ? for help.
"/var/mail/myers": 1 message 1 new
>N  1 myers@thrain.local    Thu Aug 16 10:02  13/452   "Output from your job "
? 1
Message 1:
From myers@thrain.local  Thu Aug 16 10:02:07 2018
X-Original-To: myers
Delivered-To: myers@thrain.local
Subject: Output from your job a00008018639aa
Date: Thu, 16 Aug 2018 10:02:05 -0400 (EDT)
From: myers@thrain.local (Atrun Service)

Hello, World!

? q
Saved 1 message in mbox

Downloading a large file at a specified time

So how can we download a file? Another Unix utility, the “curl” command,2 will automatically transfer a file from a specified URL. I’m going to use it to download a 475MB file containing data from LIGO’s first detection of colliding black holes,3 which will come from https://losc.ligo.org/archive/data/O1_16KHZ/1126170624/L-L1_LOSC_16_V1-1126256640-4096.hdf5.

By default, curl will output whatever it downloads to “standard output,” which means it will spew out into the terminal window. To avoid that, and cause curl to save the data to a file of the same name, I will add the “-O” flag (that is a capital letter Oh). And as it turns out, that URL is not the real URL for the file, it leads to a redirect, so I will also include the “-L” flag to tell curl to follow the redirect. Finally, curl can be very verbose while it operates, to display download status. But for our purpose we just want it to work silently, so I’ll add the “-s” flag.

Also, I want to time how long this takes, so I’ll prefix the curl command with the Unix “time” command.

And I want to put this on my desktop. When you first open the Terminal app your default directory (“current working directory”) is your home directory, and your desktop is a subdirectory (folder) called “Desktop”. So I’ll use the Unix “cd” (“change directory”) command to go down into that subfolder first.

Here’s how I do all this:

thrain:myers> date
Thu Aug 16 11:14:51 EDT 2018
thrain:myers> at 1117
cd Desktop
time curl -O -L -s https://losc.ligo.org/archive/data/O1_16KHZ/1126170624/L-L1_LOSC_16_V1-1126256640-4096.hdf5
^D
job 15 at Thu Aug 16 11:17:00 2018

After a short wait I find the queue is empty, and the file is on my Desktop. But since it is a large file it actually takes several minutes for it to finish downloading, and only after that does the output show up in the Unix mail queue:

thrain:myers> mail
Mail version 8.1 6/6/93.  Type ? for help.
"/var/mail/myers": 1 message 1 new
>N  1 myers@thrain.local    Thu Aug 16 11:23  16/482   "Output from your job "
? 1
Message 1:
From myers@thrain.local  Thu Aug 16 11:23:07 2018
X-Original-To: myers
Delivered-To: myers@thrain.local
Subject: Output from your job a0000f018639f5
Date: Thu, 16 Aug 2018 11:23:07 -0400 (EDT)
From: myers@thrain.local (Atrun Service)


real    5m56.723s
user    0m24.240s
sys     0m7.400s

? q
Saved 1 message in mbox

As you can see, it took almost 6 minutes to download the file.

Learning more

You can learn more about any of these Unix commands by reading the Unix Manual pages, using the Unix “man” command. For example, saying “man curl” will tell you more about the curl command, and saying man time will tell you more about the Unix “time” command. Saying “man at” can help you understand how to use the relative time features of the at command, such as

  at now + 12 hours

References and Notes

  1. “Mac OS X: at command not working” on StackExchange site “superuser.com”, https://superuser.com/questions/43678/mac-os-x-at-command-not-working
  2. On some versions of Unix you can use the wget command, but this is not available on the Mac
  3. Data release for event GW150914, from the LIGO Open Science Center, https://losc.ligo.org/events/GW150914/
Skip to toolbar