Wednesday 22 June 2016

Playing with Unix "at" spool

Unix at is a handy tool to schedule one time jobs.
all u need to do is, have at installed, and run:

at now + 15 min
at> ls >/tmp/test
at> ctrl+d

this will schedule a job for u.

This will create a spooled job file at: /var/spool/at.
The list of spooled jobs looks like this:

[root@feanor at]# ls -ltr
total 128
drwx------. 2 daemon daemon    6 Oct  7  2014 spool
-rwx------  1 root   root   5593 Jun 22 07:08 a000010174f96b
-rwx------  1 root   root   5581 Jun 22 07:15 a000020174f971
-rwx------  1 root   root   5581 Jun 22 07:15 a000030174f972
-rwx------  1 root   root   5576 Jun 22 07:18 a000040174f974
-rwx------  1 root   root   5576 Jun 22 07:18 a000050174f975
-rwx------  1 root   root   5576 Jun 22 07:18 a000060174f975
-rwx------  1 root   root   5576 Jun 22 07:18 a000070174f975
-rwx------  1 root   root   5579 Jun 22 07:18 a000080174f975
-rwx------  1 root   root   5576 Jun 22 07:18 a000090174f975
-rwx------  1 root   root   5576 Jun 22 07:18 a0000a0174f975
-rwx------  1 root   root   5576 Jun 22 07:18 a0000b0174f975
-rwx------  1 root   root   5576 Jun 22 07:18 a0000c0174f975
-rwx------  1 root   root   5577 Jun 22 07:18 a0000d0174f975
-rwx------  1 root   root   5577 Jun 22 07:19 a0000e0174f975
-rwx------  1 root   root   5576 Jun 22 07:19 a0000f0174f976
-rwx------  1 root   root   5577 Jun 22 07:19 a000100174f976
[root@feanor at]#
 

If you notice, the spool file name is in hex decimal.
The file name is decoded as follows:
a0-000f-0174f976
where:
- the 1stpart i am not sure what it represents, looks like it is reserved.
- the 2nd part is the job count in Hex, starting at 0x1 counting in hex until "0xf" (16) then counts to "0x10" (17) and so on.
Once the node is rebooted this count resets.
- the 3rd part is the important one, is the number of minutes since 1-1-1970 until the time of the job execution.
This is how the atd tell which job runs when.

Taking a look at the file contents, it looks like a normal shell script file with a lot of variables.
It defines, user, home shell path and lots of other variables.
last part of it is interesting part where it actually runs the job:

[root@feanor at]# tail a000100174f976
XAUTHORITY=/tmp/kde-root/xauth-0-_0; export XAUTHORITY
OLDPWD=/var/spool/at/spool; export OLDPWD
cd /var/spool/at || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
${SHELL:-/bin/sh} << 'marcinDELIMITER1d5dd9b1'
pwd

marcinDELIMITER1d5dd9b1
[root@feanor at]#


So looking at this, this job was just running a pwd commad.

So knowing this info, we can construct an at spool file similar to this one and have it run any thing for us.
To do this we can make use of the date command:

date +%s ; date +%s -d "now + 10 sec"

[root@feanor at]# date +%s ; date +%s -d "now + 10 sec"
1466595254
1466595264
[root@feanor at]#


which will return the number of seconds since 1-1-1970 and just divid this by 60 for any future time we want.

A script that uses this could look like this:

[root@feanor at]# cat create_at_spool.sh
TIME_SPEC=$1
CMD=$2

DECTIME=$(date +%s -d "${TIME_SPEC}")

TIMEPART=$(echo " obase=16; `echo "${DECTIME}/60"|bc` "|bc)
JOBPART="a001000"
echo ${JOBPART}${TIMEPART}

cp /var/spool/at/at_template.spool /var/spool/at/${JOBPART}${TIMEPART}

echo "\${SHELL:-/bin/sh} << 'marcinDELIMITER'">>/var/spool/at/${JOBPART}${TIMEPART}
echo "${CMD}" >>/var/spool/at/${JOBPART}${TIMEPART}
echo "marcinDELIMITER">>/var/spool/at/${JOBPART}${TIMEPART}
You have new mail in /var/spool/mail/root
[root@feanor at]#


One issue i noticed is that atd doesn't pick up the job from its own, it either needs to be tiggered using atd -s or another at command is run.
I will keep looking into this and update my results.



No comments:

Post a Comment