in general

unfortunately the minimum time-unit usable with at is minutes – no seconds or milliseconds.

timing non-repetative tasks

tasks that are just run once but at a certain time or date

at ist not installed per default under centos/redhat, you will have to install it via:

[root@CentOS7 ~]# yum install at
[root@CentOS7 ~]# service atd start; # start the at service
[root@CentOS7 ~]# service atd status; # check service status
Redirecting to /bin/systemctl status  atd.service
● atd.service - Job spooling tools
   Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
   Active: active (running) since Do 2017-06-22 10:41:24 CEST; 14s ago
 Main PID: 4557 (atd)
   CGroup: /system.slice/atd.service
           └─4557 /usr/sbin/atd -f

enable service start on boot:

thanks to systemd this has been unified across distributions.

systemctl enable atd.service; # make service start on boot

# pre systemd-versions of debian
update-rc.d atd enable
# pre systemd-versions of centos
[root@CentOS7 user]# chkconfig atd on

examples:

At allows fairly complex time specifications, extending the POSIX.2 standard.

It accepts times of the form HH:MM to run a job at a specific time of day. (If that time is already past, the next day is assumed.)

You may also specify midnight, noon, or teatime (4pm) and you can have a time-of-day suffixed with AM or PM for running in the morning or the
evening.

You can also say what day the job will be run, by giving a date in the form month-name day with an optional year, or giving a date of the form MMDD[CC]YY, MM/DD/[CC]YY, DD.MM.[CC]YY or [CC]YY-MM-DD.

The specification of a date must follow the specification of the time of day.

You can also give times like now + count time-units, where the timeunits can be minutes, hours, days, or weeks and you can tell at to run the job today by suffixing the time with today and to run the job tomorrow by suffixing the time with tomorrow.

For example:

to run a job at 4pm three days from now, you would do at 4pm + 3 days

to run a job at 10:00am on July 31, you would do at 10am Jul 31

to run a job at 1am tomorrow, you would do at 1am tomorrow.

uname -a; # tested with but should be working pretty cross-distribution
Linux debian 3.16.0-4-686-pae #1 SMP Debian 3.16.43-2 (2017-04-30) i686 GNU/Linux

at 14:45
touch create_this_file
# Ctrl+D to quit at
at> 
job 1 at Thu May 18 14:45:00 2017 <- task is scheduled

at 14:47
touch create_another_file
# Ctrl+D to quit at

at now + 5 minutes
touch this_file_will_be_created_in_five_minutes
# Ctrl+D to quit at

at 11:00 july 2
touch this_file_will_be_created_on_this_date
# Ctrl+D to quit at

suse12:~ # at noon tomorrow; # also valid, will run 12:00 the next day

wall "3 minutes have passed" | at now +3min; # one-liner

atq; # list all scheduled jobs
4       Sun Jul  2 11:00:00 2017 a root
1       Thu May 18 14:45:00 2017 a root
2       Thu May 18 14:47:00 2017 a root

at -c 4; # show me details about job number 4
# essentially prints out the auto-generated job-script-file: /var/spool/atjobs/a00005017d03d8 
atrm 4; # remove job number 4

at -f /path/script.sh now + 1 hour; # run that script

scheduling the start of grafical programs:

can be done with at as well, but you will have to find out on what $DISPLAY your desktop is currently operating.

so start a terminal INSIDE YOUR GNOME OR KDE DESKTOP (you will get wrong values if logging in via ssh)

echo $DISPLAY

now you could start that like this:

vim /scripts/start_firefox.sh; # create new script with that content

#!/bin/bash
export DISPLAY=:0.0
/usr/bin/firefox

ESC :x # save quit vim
chmod u+x /scripts/start_firefox.sh; # mark script runnable

schedule it:

at -f /scripts/start_firefox.sh now +1min

GUI alternatively:

apt-get install gnome-schedule;

config files:

controls what users are allowed to use at. root is always allowed.

if there is an at.allow file the at.deny file is ignored.

at.allow.man.txt

at.deny.man.txt

example content:

suse12:~ # cat /etc/at.deny
root
bin
daemon
lp
mail
news
uucp
games
man
wwwrun
ftp
nobody

root@Debian8:~# cat /etc/at.deny
alias
backup
bin
daemon
ftp
games
gnats
guest
irc
lp
mail
man
nobody
operator
proxy
qmaild
qmaill
qmailp
qmailq
qmailr
qmails
sync
sys
www-data

[root@CentOS7 ~]# cat /etc/at.deny
(empty, nuthin'!)

so if you add a user to that list, the user will get this error:

bob@suse12:~> at 11 am mar 20
You do not have permission to use at.

when trying to use at

where at jobs are stored as files:

everything under linux is represented as files…

suse12:~ # at noon tomorrow
warning: commands will be executed using /bin/sh
at> ls /etc
at> 
job 5 at Fri Jun 23 12:00:00 2017
suse12:~ # ll /var/spool/atjobs/
insgesamt 12
-rwx------ 1 root root 3015 22. Jun 11:14 a00005017d03d8
-rw------- 1 at   at      6 22. Jun 11:13 .SEQ

essentially it is a auto-generated script that looks like this:

suse12:/var/spool/atjobs # cat a00005017d03d8
#!/bin/sh
# atrun uid=0 gid=0
# mail user 0
umask 22
LESSKEY=/etc/lesskey.bin; export LESSKEY
MANPATH=/usr/local/man:/usr/share/man; export MANPATH
NNTPSERVER=news; export NNTPSERVER
HOSTNAME=suse12; export HOSTNAME
XKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDB; export XKEYSYMDB
HOST=suse12; export HOST
HISTSIZE=1000; export HISTSIZE
PROFILEREAD=true; export PROFILEREAD
MORE=-sl; export MORE
OLDPWD=/home/bob; export OLDPWD
USER=bob; export USER
LS_COLORS=no=00:fi=00:di=01\;34:ln=00\;36:pi=40\;33:so=01\;35:do=01\;35:bd=40\;33\;01:cd=40\;33\;01:or=41\;33\;01:ex=00\;32:\*.cmd=00\;32:\*.exe=01\;32:\*.com=01\;32:\*.bat=01\;32:\*.btm=01\;32:\*.dll=01\;32:\*.tar=00\;31:\*.tbz=00\;31:\*.tgz=00\;31:\*.rpm=00\;31:\*.deb=00\;31:\*.arj=00\;31:\*.taz=00\;31:\*.lzh=00\;31:\*.lzma=00\;31:\*.zip=00\;31:\*.zoo=00\;31:\*.z=00\;31:\*.Z=00\;31:\*.gz=00\;31:\*.bz2=00\;31:\*.tb2=00\;31:\*.tz2=00\;31:\*.tbz2=00\;31:\*.xz=00\;31:\*.avi=01\;35:\*.bmp=01\;35:\*.fli=01\;35:\*.gif=01\;35:\*.jpg=01\;35:\*.jpeg=01\;35:\*.mng=01\;35:\*.mov=01\;35:\*.mpg=01\;35:\*.pcx=01\;35:\*.pbm=01\;35:\*.pgm=01\;35:\*.png=01\;35:\*.ppm=01\;35:\*.tga=01\;35:\*.tif=01\;35:\*.xbm=01\;35:\*.xpm=01\;35:\*.dl=01\;35:\*.gl=01\;35:\*.wmv=01\;35:\*.aiff=00\;32:\*.au=00\;32:\*.mid=00\;32:\*.mp3=00\;32:\*.ogg=00\;32:\*.voc=00\;32:\*.wav=00\;32:; export LS_COLORS
XNLSPATH=/usr/share/X11/nls; export XNLSPATH
HOSTTYPE=x86_64; export HOSTTYPE
QEMU_AUDIO_DRV=pa; export QEMU_AUDIO_DRV
FROM_HEADER=; export FROM_HEADER
PAGER=less; export PAGER
CSHEDIT=emacs; export CSHEDIT
XDG_CONFIG_DIRS=/etc/xdg; export XDG_CONFIG_DIRS
MINICOM=-c\ on; export MINICOM
PATH=/home/bob/bin:/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/bin:/usr/bin/X11:/usr/games; export PATH
MAIL=/var/spool/mail/bob; export MAIL
CPU=x86_64; export CPU
PWD=/root; export PWD
INPUTRC=/home/bob/.inputrc; export INPUTRC
LANG=de_DE.UTF-8; export LANG
PYTHONSTARTUP=/etc/pythonstart; export PYTHONSTARTUP
AUDIODRIVER=pulseaudio; export AUDIODRIVER
GPG_TTY=/dev/pts/0; export GPG_TTY
HOME=/root; export HOME
SHLVL=2; export SHLVL
QT_SYSTEM_DIR=/usr/share/desktop-data; export QT_SYSTEM_DIR
OSTYPE=linux; export OSTYPE
LESS_ADVANCED_PREPROCESSOR=no; export LESS_ADVANCED_PREPROCESSOR
SDL_AUDIODRIVER=pulse; export SDL_AUDIODRIVER
ALSA_CONFIG_PATH=/etc/alsa-pulse.conf; export ALSA_CONFIG_PATH
XCURSOR_THEME=DMZ; export XCURSOR_THEME
LS_OPTIONS=-A\ -N\ --color=tty\ -T\ 0; export LS_OPTIONS
WINDOWMANAGER=env\ GNOME_SHELL_SESSION_MODE=classic\ SLE_CLASSIC_MODE=1\ gnome-session\ --session\ gnome-classic; export WINDOWMANAGER
LOGNAME=bob; export LOGNAME
MACHTYPE=x86_64-suse-linux; export MACHTYPE
LESS=-M\ -I\ -R; export LESS
G_FILENAME_ENCODING=@locale,UTF-8,ISO-8859-15,CP1252; export G_FILENAME_ENCODING
XDG_DATA_DIRS=/usr/share; export XDG_DATA_DIRS
LESSOPEN=lessopen.sh\ %s; export LESSOPEN
LESSCLOSE=lessclose.sh\ %s\ %s; export LESSCLOSE
G_BROKEN_FILENAMES=1; export G_BROKEN_FILENAMES
COLORTERM=1; export COLORTERM
cd /root || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
ls /etc

manpages:

atd.man.tx

at.man.tx

batch.man.txt

links:

http://dwaves.de/2017/05/18/linux-bash-timing-scheduling-schedule-repeated-tasks-processes-cron-crontab/

http://dwaves.de/2017/05/18/linux-bash-start-job-when-system-is-idle-batch-run-task-when-1min-5min-or-15min-cpu-load-average-reaches-threshold/

https://wiki.debian.org/Daemon#Enable.2Fdisable_daemons

admin