May 17, 2015
I like to let large downloads run at night. “Easy, use the Unix at
command”, you say. Unfortunately the at
command has been horribly mangled in OSX Yosemite 10.10.3, but it can be made to behave itself. You will have to be able to run it as su
, or using sudo
, but here we go…
at
on OSX depends on atrun
, which is not enabled by default. From the at
man page:
Note that at is implemented through the launchd(8) daemon periodically invoking atrun(8), which is disabled by default. See atrun(8) for information about enabling atrun.
So the first thing you will have to do is:
launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist
(See man atrun
for more details.)
If you try to just schedule a job without sudo
, or being the su
, it will complain that it is unable to regain privileges. So the format is thus:
sudo at HHMM
(you can also use HH:MM
, if you please, check man at
for the permutations.)
This will open a blank line on your terminal, at which you can enter:
sudo -u <username> curl -O http://foo.bar/baz.iso
then ^D
to quit and save the job. If you want to save the output from the job, you can use:
sudo -u <username> curl -O http://foo.bar/baz.iso > /Users/username/at_output.txt 2>&1
The sudo
in the job command won’t require a password, so the job will run unattended. Once you have a job or jobs set up you can run sudo atq
to view the queued jobs and sudo atrm #
to delete a specific job by number.
If you’re fortunate, and clever, enough to be using the Z-shell, you can use zsh’s builtin sched
command. Sched does not need superuser privileges. sched
by itself lists queued jobs, while something like:
sched -o HH:MM curl -O http://foo.bar/baz.iso
will queue up a task. (Note the colon in the HH:MM
, this is required.) The -o
flag is recommended for jobs which will output information to the terminal; from the man page:
This (the -o flag) should be used with any scheduled event that produces visible output to the terminal; it is not needed, for example, with output that updates a terminal emulator’s title bar.
Running sched -#
will remove a job. If I want a job to run overnight I just use something like sched 02:00
, and sched will figure out that it’s the next 0200, not the previous one!
More detail can be found in the unreasonably large man zshall
, search for ZSH/SCHED.