为什么在Linux中需要“ at”命令?


38

我正在研究at使用命令的代码。我环顾四周,发现它用于执行批处理作业。它用于计划作业。作为输入,给出命令和相对或绝对时间。

因此,我的第一个问题是:为什么at使用该命令?在什么情况下需要使用at?当有一些bash脚本代码试图卸载软件并且一些后台服务要重新启动时,我遇到了它。

我的第二个问题:将任何命令作为批处理作业执行与在直接调用命令(或在子Shell中)执行命令之间有什么区别?

Answers:


47

伯恩哈德的回答是正确的:在多用户系统中,对于提交工作的人和他的同事来说,在晚上不方便的几个小时执行繁重的程序的能力特别方便。这是“玩的很好”的一部分。

我完成了大部分博士学位。通过这种方式进行计算,将脚本与漂亮的命令结合在一起,每当其他人使机器忙碌时,该命令就会降低我的工作优先级,同时保留其夜间占用所有系统资源的能力。

我使用了相同的命令来检查我的程序是否正在运行,并在必要时重新启动它。

另外,您应该记住,at是在screen,tmux等之前编写的,因此这是拥有独立外壳的简单方法,即,一旦退出系统,该外壳将不会消失。

最后,您还应该注意到它与cron不同,cron也已经存在了很长时间。区别在于这样的事实:at偶尔会重复执行,而cron更适合确实需要以固定间隔永远执行的系统作业:实际上,at提供了您自己的环境和您自己的设置(和选择),而cron使用最少的一组环境变量(例如,检查PATH中的差异)。


15
同样值得指出的是,与cron的另一个不同之处在于,at它可以像安排作业一样保留环境:相同的工作目录,环境变量,...
CarlosCampderrós2013年

10
还有batch,它几乎与相同at,但是将等待一个低负载,并且显然at -q z可以自己完成工作,而at -q Z等待时间,然后等待负载下降,也可以完成工作。哇,很少使用的功能!
Ulrich Schwarz 2013年

16

at当我需要对数据进行一些繁重的处理时,如果我不想在计算机后面时,需要在夜间执行这些命令,则可以使用该命令。我当然可以在离开后立即开始该过程,但这是我容易忘记的事情。

命令的结果与定期执行脚本或命令没有什么不同。


15

遇到诸如此类的问题时,请始终查阅手册页。他们会很有启发性。

它能做什么

摘录于手册页

NAME
       at, batch, atq, atrm - queue, examine or delete jobs for later execution

DESCRIPTION
       at  and  batch  read  commands  from  standard  input or a specified file
       which are to be executed at a later time, using /bin/sh.

用法

工具的用法:

Usage: at [-V] [-q x] [-f file] [-mldbv] timespec ...
       at [-V] [-q x] [-f file] [-mldbv] -t time
       at -c job ...
       atq [-V] [-q x]
       atrm [-V] job ...
       batch

at包括4个命令(atatqatrm,和batch)。您可以使用atbatch调度作业,atq查看已调度的作业以及atrm在作业运行之前将其删除。

$ at -f <cmd> timspec

时间规格

at可以用不同的方式指定运行作业的时间。

手册页摘录形式

At允许相当复杂的时间规范,从而扩展了POSIX.2标准。它接受格式为HH:MM的时间以在一天的特定时间运行作业。(如果该时间已经过去,则假定为第二天。)您也可以指定午夜,中午或下午茶时间(下午4点),并且可以在一天的后缀AM或PM进行早上跑步或晚上。您还可以通过指定月份名称日期(带可选年份)的日期或MMDD [CC] YY,MM / DD / [CC] YY格式的日期,来说明工作的日期。 DD.MM. [CC] YY或[CC] YY-MM-DD。日期的指定必须遵循一天中时间的指定。您还可以指定类似现在的时间+计算时间单位,其中时间单位可以是分钟,小时,天,

例子

说你有这个shell脚本。

$ cat mycrontest.sh

#!/bin/bash
 echo "It is now $(date +%T) on $(date +%A)"

样品运行:

$ ./mycrontest.sh
It is now 18:37:42 on Friday

职位提交样本:

$ at -f mycrontest.sh  10pm tomorrow
job 14 at Sun Jul  8 22:00:00 2007

$ at -f mycrontest.sh 2:00 tuesday
job 15 at Tue Jul 10 02:00:00 2007

$ at -f mycrontest.sh 2:00 july 11
job 16 at Wed Jul 11 02:00:00 2007

$ at -f mycrontest.sh 2:00 next week
job 17 at Sat Jul 14 02:00:00 2007

参考文献


我的atCygwin安装上似乎有一个非常不同的版本-它似乎没有链接到batch,根本不支持任何简短选项,没有安静选项,并且没有maninfo页面包括在内。
Hashim

@Hashim-Cygwin是它自己的野兽。
slm

6

您可以使用at,batch或cron这三个命令之一在UNIX / Linux中执行批处理作业。

使用特定的日期和时间安排作业

Syntax:

    $ at time date
For example, to schedule a job at 11 am on May 20, use the following at command.

    $ at 11 am may 20

是的,我对“ at”及其用法有一定的了解。其他人回答得更相关。
Akshay Patil,2013年

5

您的网络管理员通知您,从晚上7点开始到凌晨2点结束,您的Web服务器将进行一些维护。您希望事先提供维护通知,并且希望从系统中获得最大的正常运行时间。您要整夜熬夜,准备运行各种命令,然后稍后再次启动它吗?不,您想at用来安排这些任务,然后上床睡觉/玩天际,忘掉它。


1

at也可以是触发提醒的便捷方法。我当前的开发机器正在运行OSX,因此,我拼凑at的简单notify.bash方法会非常有用:

$ at 5pm
notify.bash -t 'Work is over' -m "Don't forget to rollback INT environment"
^D
$ at now + 15 minutes
notify.bash -m 'Check tests' -l 'http://integration.example.com/jobs/XXXX'
^D
$ at now + 10 minutes
notify.bash -m 'Check the fridge, pudding should be done!'
^D

notify.bash

#!/bin/bash

DEFAULT_TITLE='Hey! Listen!'
TITLE="$DEFAULT_TITLE"
LINK=
MESSAGE=

function args.help () {
    local error="$1"
    if [ "$error" ]; then
        echo >&2 "$error"
    fi
    cat >&2 <<EOF
Usage $0 <options>

Displays a message using an Applescript notification box

Options
-------

--title <text>    Sets the title, otherwise the default is used ("$DEFAULT_TITLE")
 -t     <text>    Alias for --title

--link  <url>     Add a button to open a link
 -l     <url>     Alias for --link

--body  <text>    Set the message body
 -m     <text>    Alias for --body
EOF
}

function args.verify-not-empty () {
    local value="$1"
    local varname="$2"

    if [ "$value" ]; then
        echo "$value"
    elif [ "$varname" ]; then
        args.help "$varname cannot handle an empty argument"
        exit 1
    else
        args.help \
            "The programmer forgot to include context, something was empty which shouldn't have been, but I can't tell you much more than that. Sorry :("
        exit 1
    fi
}

function args.parse () {
    while [ "$1" ]
    do
        case "$1" in
            '-t' | '--title')
                shift
                TITLE=$(args.verify-not-empty "$1" title)
                shift
                ;;
            '-l' | '--link')
                shift
                LINK=$(args.verify-not-empty "$1" link)
                shift
                ;;
            '-m' | '--body')
                shift
                if [[ "$1" = '-' ]]; then
                    MESSAGE=$(cat -)
                else
                    MESSAGE="$1"
                fi
                MESSAGE=$(args.verify-not-empty "$MESSAGE" body)
                shift
                ;;
            *)
                args.help "Unrecognized argument: $1"
                exit 1
        esac
    done
    if [[ ! "$MESSAGE" ]]; then
        args.help "Message body was not specified"
        exit 1
    fi
}

function message.display-no-link () {
    osascript > /dev/null <<EOF
tell application "Finder"
  activate
  display alert "$TITLE" ¬
          message "$MESSAGE" ¬
          buttons { "Acknowledge" } ¬
          default button "Acknowledge"
end tell
return
EOF
}

function message.display-with-link () {
    osascript > /dev/null <<EOF
tell application "Finder"
  activate
  display alert "$TITLE" ¬
          message "$MESSAGE\n\nClick 'Open Link' to go to $LINK" ¬
          buttons { "Acknowledge", "Open Link" } ¬
          default button "Open Link"
          set response to button returned of the result
          if response is "Open Link" then open location "$LINK"
end tell
return
EOF
}

function message.display () {
    if [ "$LINK" ]; then
        message.display-with-link
    else
        message.display-no-link
    fi
}

args.parse "$@"
message.display
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.