Frage

Gibt es eine Möglichkeit, das Datum eines Auftrags zu ändern, die mit dem Unix-at Befehl ausgegeben wurde?

Ich muß dies tun, weil meine Anwendung zu viele Arbeitsplätze zur gleichen Zeit geplant, die die Maschine zum Erliegen bringen wird.

War es hilfreich?

Lösung

Dies ist wahrscheinlich die Umsetzung abhängig, aber auf meinem System kann ich den Job umbenennen wie folgt:

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

Die letzten 8 Hex-Ziffern im Dateinamen ist die Anzahl der Minuten von der Unix-Epoche, das die Zeit bestimmt, den Job auszuführen. Increment, dass durch die Anzahl der Minuten Verzögerung.

Edit:

Im Folgenden finden Sie ein Bash-Skript zu automatisieren die Schritte oben. Hier sind einige Beispiele lautet:

Erstellen Sie einen Job:

$ 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

Umplanen den Auftrag für eine Stunde später:

$ 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

Umplanen es für 15 Minuten früher:

$ 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

Jetzt einen Tag hinzu:

$ 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

Sie können eine Warteschlange angeben:

$ sudo atrs -q b 141 120

Sie einen Testlauf:

$ 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

Hier ist das Skript:

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

Andere Tipps

Dies wird die Arbeit eine neue ID für die neue Zeit zuweisen.

at -c OLDJOBID | at NEWTIME
atrm OLDJOBID

Ich bin nicht sicher, ob es eine Möglichkeit, sie für eine andere Zeit neu zu planen, aber man kann sich von at wie diese vollständig entfernen:

Erste Liste der Jobs:

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

Dann entfernen sie:

$ at -d 9944
$ at -d 9945

Sie können sie dann neu erstellen, wenn Sie wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top