Перенос на работу

Есть ли способ изменить дату задания, которое было выпущено командой unix at команде?

Мне нужно сделать это, потому что в моем приложении запланировано слишком много заданий одновременно, что приведет к остановке машины.

Вероятно, это зависит от реализации, но в моей системе я могу переименовать работу следующим образом:

 $ # Bash $ sudo ls -l /var/spool/cron/atjobs -rwx------ 1 username daemon 3782 Nov 29 11:24 a00078014854e8 $ atq 120 Mon Nov 29 11:44:00 2010 a username $ printf "%x\n" $((16#14854e8 + 60*2)) # 2 hour delay 1485560 $ sudo mv /var/spool/cron/atjobs/a00078014854e8 /var/spool/cron/atjobs/a0007801485560 $ atq 120 Mon Nov 29 13:44:00 2010 a username 

Последние 8 шестнадцатеричных цифр в имени файла – это количество минут от Unix Epoch, которое определяет время выполнения задания. Увеличьте это на количество минут до задержки.

Редактировать:

Ниже приведен сценарий Bash для автоматизации описанных выше шагов. Вот несколько примеров:

Создать работу:

 $ date Mon Nov 29 20:00:00 CST 2010 $ echo true | at now + 1 hour $ atq 140 Mon Nov 29 21:00:00 2010 a username 

Перепланируйте работу в течение часа:

 $ sudo atrs 140 60 Job 140 in Queue "a" rescheduled from Mon Nov 29 21:00:00 CST 2010 to Mon Nov 29 22:00:00 CST 2010 

Перенести его на 15 минут раньше:

 $ sudo atrs 140 -15 Job 140 in Queue "a" rescheduled from Mon Nov 29 22:00:00 CST 2010 to Mon Nov 29 21:45:00 CST 2010 

Теперь добавьте день:

 $ sudo atrs 140 $((60 * 24)) Job 140 in Queue "a" rescheduled from Mon Nov 29 21:45:00 CST 2010 to Mon Nov 30 21:45:00 CST 2010 

Вы можете указать очередь:

 $ sudo atrs -qb 141 120 

Сделайте сухой ход:

 $ sudo atrs -n 140 30 Job 140 in Queue "a" Current job time: Mon Nov 30 21:45:00 2010 Proposed job time: Mon Nov 30 22:15:00 2010 

Вот сценарий:

 #!/bin/bash # atrs - reschedule at jobs # atrs [-n] [-q queue] job [-|+]minutes # by Dennis Williamson 2010-11-29 # in response to http://stackoverflow.com/questions/4304631/rescheduling-an-at-job # for Bash 3.2 or greater # this script assumes that the last eight characters of the at job filename is # a sequence of hex digits representing the number of minutes starting at # the Unix epoch that is the time that the job is scheduled to be run LC_COLLATE=C export LC_TIME=C shopt -s nullglob mvcmd=/bin/mv datecmd=/bin/date GREP_OPTIONS= grepcmd=/bin/grep atqcmd=/usr/bin/atq atjobs=/var/spool/cron/atjobs declare -r tab=$'\t' declare -r NOEXIT=0 declare -r EXIT=1 # it's not necessary to bitmap the errors, but I just wanted to declare -r ERROPTS=1 declare -r ERROARG=2 declare -r ERRARGS=4 declare -r ERRQUNM=8 declare -r ERRNOJB=16 declare -r ERRMVFL=32 declare -r ERRNOCH=64 declare -r ERRNINT=128 declare -r DRYRUN=255 # not otherwise possible to reach this number queue=a err=0 error () { (( err |= ${2:-0} )) msg+="${3:+$3\n}" if (( $1 == $EXIT )) then printf "$msg" printf "Usage: ${0##*/} [-n] [-q queue] job [-|+]minutes\n" printf " the default queue is a\n" printf " -n = dry run (default if not superuser)\n" exit $err else return fi } # Process options and arguments options=':q:nh' while getopts $options option do case $option in q ) queue=$OPTARG;; n ) execute=1; ret=$DRYRUN;; # do dry run h ) error $EXIT $DRYRUN;; \? ) if (( (err & ERROPTS) != ERROPTS )) then error $NOEXIT $ERROPTS "Unknown option." fi;; * ) error $NOEXIT $ERROARG "Missing option argument.";; esac done shift $(($OPTIND - 1)) if [[ ! $queue =~ ^[a-zA-Z=]$ ]] then error $NOEXIT $ERRQUNM "Invalid queue name." fi if (( $# != 2 )) then error $NOEXIT $ERRARGS "Job number and offset in minutes are required." fi if [[ $1 =~ ^[0-9]+$ ]] then job=$1 else error $NOEXIT $ERRNINT "Job number must be a positive integer." fi if [[ $2 =~ ^[-+]?[0-9]+$ ]] then minutes=$2 else error $NOEXIT $ERRNINT "Minutes must be an integer." fi if (( err != 0 )) then error $EXIT fi # make preparations if (( $EUID == 0 )) then printf -v old "%05x" "$job" prefix="$atjobs/$queue$old" file=($prefix*) if [[ -z $file || ! -e $file ]] then error $EXIT $ERRNOJB "Job not found." fi oldhex="${file#$prefix}" oldminutes=$((16#$oldhex)) newminutes=$((oldminutes + minutes)) printf -v newhex "%08x" "$newminutes" from=$($datecmd -d @"$(($oldminutes * 60))") to=$($datecmd -d @"$((newminutes * 60))") else if (( execute == 0 )) then printf "You must be superuser to reschedule jobs. The job will be listed instead.\n" execute=1 # do dry run ret=$DRYRUN fi fi # perform action if (( execute == 0 )) then if [[ $file != $prefix$newhex ]] then if $mvcmd "$file" "$prefix$newhex" then printf 'Job %s in Queue "%s" rescheduled\n' "$job" "$queue" printf "from %s\n" "$from" printf "to %s\n" "$to" else error $EXIT $ERRMVFL "Reschedule failed." fi else error $EXIT $ERRNOCH "No change, times are the same." fi else jobdate=$($atqcmd -q $queue | $grepcmd "^$job$tab") if [[ -n $jobdate ]] then jobdate=${jobdate#$job$tab} jobdate=${jobdate%% $queue *} newjobdate=$($datecmd +%c -d "$jobdate + $minutes minutes") if [[ $jobdate != $newjobdate ]] then printf 'Job %s in Queue "%s"\n' "$job" "$queue" printf "Current job time: %s\n" "$jobdate" printf "Proposed job time: %s\n" "$newjobdate" else error $EXIT $ERRNOCH "Proposed time would result in no change." fi else error $EXIT $ERRNOJB "Job not found." fi fi exit $ret 

Это назначит задание новый идентификатор для нового времени.

 at -c OLDJOBID | at NEWTIME atrm OLDJOBID 

Я не уверен, есть ли способ перенести их в другое время, но вы можете полностью удалить их из:

Сначала перечислите задания:

 $ at -l 9944 2010-11-29 15:00 a dogbane 9945 2010-11-29 15:00 a dogbane 

Затем удалите их:

 $ at -d 9944 $ at -d 9945 

Затем вы можете воссоздать их, если хотите.