2010-11-29 3 views
5

Y at-il un moyen de modifier la date d'un travail qui a été émis avec la commande unix at?Replanification d'un travail at

J'ai besoin de faire cela parce que mon application a programmé trop de travaux en même temps, ce qui mettra la machine à l'arrêt.

Répondre

9

C'est la mise en œuvre dépend probablement, mais sur mon système je peux renommer le travail comme ceci:

$ # 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 

Les 8 derniers chiffres hexadécimaux dans le nom de fichier est le nombre de minutes de l'époque Unix qui détermine le temps pour exécuter le travail. Incrémentez cela du nombre de minutes à retarder.

Edit:

est Ci-dessous un script Bash pour automatiser les étapes ci-dessus. Voici quelques pistes par exemple:

Créer un emploi:

$ 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 

Réordonnancer le travail pendant une heure plus tard:

$ 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 

REPORTER pendant 15 minutes plus tôt:

$ 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 

Maintenant, ajoutez un jour:

$ 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 

Vous pouvez spécifier une file d'attente:

$ sudo atrs -q b 141 120 

Faites une marche à sec:

$ 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 

Voici le scénario:

#!/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 
+0

Un peu hackish mais cela fonctionne réellement. C'était vraiment une bouée de sauvetage. Tu gères! –

+1

@Michael: Oui, je suppose que c'est le cas, bien que l'enregistrement de la planification dans le nom de fichier en premier lieu est d'où il provient. J'ai édité ma réponse et ajouté un script qui automatise les étapes que j'ai décrites dans ma réponse originale. –

+0

Merci pour le script shell! Travaillé comme un charme! +1 –

1

Je ne sais pas s'il y a un moyen de les rééchelonner pour un autre moment, mais vous pouvez les supprimer complètement de at comme ceci:

Première liste des emplois:

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

Ensuite, retirez-les:

$ at -d 9944 
$ at -d 9945 

Vous pouvez ensuite les recréer si vous le souhaitez.

3

Cela affectera le travail d'un nouvel identifiant pour son nouveau temps.

at -c OLDJOBID | at NEWTIME 
atrm OLDJOBID 
+0

Cela provoque la duplication de l'emballage. –

+0

@Dennis Oui, c'est le cas.Mais ça devrait être le même truc de wrapper, je ne pensais pas que ça faisait tellement de différence que le truc de wrapper était dupliqué. (Si ce n'est pas la même chose avec le wrapper, alors les trucs wrapper de l'ancien job viennent en second, donc c'est ce qui est utilisé.) –

Questions connexes