2

I would like to test an at time argument before running the at command. The use case is that I would like to run the at command on a different computer at a different time, so I want to first store the at argument, which means I want to check it when it is first entered.

Example is before:

$ atarg1="now+7mintes"
# I would like to check the above *before* running this
$ at $atarg1 <<< "echo hi there"
syntax error. Last token seen: t
Garbled time
hlovdal
  • 23,353
  • 10
  • 78
  • 148
Xu Wang
  • 8,891
  • 4
  • 40
  • 70

2 Answers2

2

You could try testing the time on GNU date. Note that this fails:

$ atarg="now+7mintes"
$ date -d "$atarg" >/dev/null 2>&1 || echo "Bad time"
Bad time

while this succeeds:

$ atarg="now+7minutes"
$ date -d "$atarg" >/dev/null 2>&1 || echo "Bad time"

In other words, when date -d is given a bad argument, date exits with a nonzero return code. This allows you to test under bash whether the date is good, at least as far as date accepting it.

I have not found any documentation to indicate that at and date use the same code to interpret dates. So, this approach has no guarantee.

Problem

It turns out that date is more flexible about its time format than at. As XuWang points out, date accepts 18minutes as shorthand for now + 18minutes but at does not:

$ date -d "18minutes"
Fri May 27 15:30:59 PDT 2016
$ echo true | at "18minutes"
syntax error. Last token seen: minutes
Garbled time
John1024
  • 97,609
  • 11
  • 105
  • 133
  • Thank you, this works good but not great. For example, date understands "18minutes" but at does not, at needs now+18minutes. – Xu Wang May 27 '16 at 21:54
  • XuWang, I see. I get the same results. I hope that @triplee's answer works for you. – John1024 May 27 '16 at 22:18
2

You could always remove the job from the queue if it succeeds. This obviously has a race condition - in the unlikely event that the command executes from the queue between submitting and removing it, you will run a command needlessly. Running true when you didn't want to has very low impact, though.

if success=$(at "$atarg" <<<true); then
    sed 's/^job \([1-9][0-9]*\) at .*/\1/' <<<"$success" | xargs atrm
    exit 0
else
    exit $?
fi
tripleee
  • 139,311
  • 24
  • 207
  • 268