Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 重新安排工作时间_Shell_Unix_At Job - Fatal编程技术网

Shell 重新安排工作时间

Shell 重新安排工作时间,shell,unix,at-job,Shell,Unix,At Job,是否有方法更改使用unixat命令发出的作业的日期 我之所以需要这样做,是因为我的应用程序在同一时间安排了太多的作业,这将导致机器完全停止。我不确定是否有办法将它们重新安排到不同的时间,但您可以像这样将它们从处完全删除: 首先列出作业: $ at -l 9944 2010-11-29 15:00 a dogbane 9945 2010-11-29 15:00 a dogbane 然后移除它们: $ at -d 9944 $ at -d 9945 如果需要,您可以重新创建它们。这可

是否有方法更改使用unix
at
命令发出的作业的日期


我之所以需要这样做,是因为我的应用程序在同一时间安排了太多的作业,这将导致机器完全停止。

我不确定是否有办法将它们重新安排到不同的时间,但您可以像这样将它们从
处完全删除:

首先列出作业:

$ at -l
9944    2010-11-29 15:00 a dogbane
9945    2010-11-29 15:00 a dogbane
然后移除它们:

$ at -d 9944
$ at -d 9945

如果需要,您可以重新创建它们。

这可能取决于实现,但根据我的系统,我可以像这样重命名作业:

$ # 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纪元开始的分钟数,它决定了运行作业的时间。按延迟的分钟数递增

编辑:

下面是一个自动化上述步骤的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 -q b 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

这将为作业的新时间分配一个新id

at -c OLDJOBID | at NEWTIME
atrm OLDJOBID

有点老套,但它确实有效。那真是个救命恩人。你太棒了@迈克尔:是的,我想是的,不过把时间表存储在文件名的第一位是它的起源。我已经编辑了我的答案,并添加了一个脚本,可以自动执行我在原始答案中概述的步骤。感谢您提供的shell脚本!工作得很有魅力+1这会导致包装材料重复。@Dennis是的,确实如此。但是它应该是相同的包装材料,我不认为它实际上与复制包装材料有多大区别。(如果它不是相同的包装材料,那么旧作业中的包装材料排在第二位,这就是使用的内容。)上面的示例at-c 15 |现在+5分钟,然后atrm 15