ทำไมเราต้องใช้คำสั่ง“ at” ใน Linux?


38

ฉันกำลังศึกษาโค้ดที่ใช้atคำสั่ง ฉันมองไปรอบ ๆ และพบว่ามันถูกใช้เพื่อเรียกใช้งานแบ็ตช์ มันถูกใช้เพื่อกำหนดเวลางาน มันถูกกำหนดให้เป็นอินพุตคำสั่งและเวลาสัมพันธ์หรือสัมบูรณ์

ดังนั้นคำถามแรกของฉันคือ: ทำไมatคำสั่งใช้? ภายใต้สถานการณ์ใดที่เราต้องใช้at? ฉันพบมันเมื่อมีรหัสสคริปต์ทุบตีพยายามถอนการติดตั้งซอฟต์แวร์และเมื่อมีการเริ่มบริการพื้นหลังบางอย่าง

คำถามที่สองของฉัน: อะไรคือความแตกต่างระหว่างการมีคำสั่งที่ดำเนินการเป็นงานแบทช์และมีคำสั่งดำเนินการในการเรียกคำสั่งโดยตรง (หรือใน subshell)?

คำตอบ:


47

การตอบกลับของแบร์นฮาร์ดนั้นถูกต้อง: ในระบบที่มีผู้ใช้หลายคนความสามารถในการรันโปรแกรมขนาดใหญ่ในเวลาไม่กี่ชั่วโมงในเวลากลางคืนนั้นสะดวกมากเป็นพิเศษสำหรับทั้งคนที่ส่งงานและเพื่อนร่วมงานของเขา มันเป็นส่วนหนึ่งของ "การเล่นที่ดี"

ฉันทำปริญญาเอกเป็นส่วนใหญ่ การคำนวณด้วยวิธีนี้การรวมสคริปต์กับคำสั่งที่ดีซึ่งลดระดับความสำคัญของงานของฉันเมื่อใดก็ตามที่คนอื่น ๆ กำลังทำให้เครื่องไม่ว่างในขณะที่ยังคงความสามารถในการทรัพยากรทรัพยากรระบบในเวลากลางคืน

ฉันใช้คำสั่งเดียวกันเพื่อตรวจสอบว่าโปรแกรมของฉันทำงานอยู่หรือไม่และเริ่มใหม่หากจำเป็น

นอกจากนี้คุณควรจำไว้ว่าที่ถูกเขียนก่อนหน้าจอ tmuxและอื่น ๆ เพื่อให้เป็นวิธีที่ง่ายที่จะมีเชลล์แยกเดี่ยวเช่นที่ไม่ตายเมื่อคุณออกจากระบบ

สุดท้ายคุณควรสังเกตว่ามันแตกต่างจาก cron ซึ่งมีมานานแล้ว ความแตกต่างอยู่ที่ความจริงที่ว่าในบางครั้งในขณะที่ cron มีการทำซ้ำดังนั้นเหมาะสำหรับงานของระบบที่ต้องดำเนินการอย่างถาวรในช่วงเวลาคงที่: ในความเป็นจริงที่ให้สภาพแวดล้อมของคุณเองด้วยการตั้งค่าของคุณเอง และตัวเลือก) ของตัวแปรสภาพแวดล้อมในขณะที่cronใช้ชุดของตัวแปรสภาพแวดล้อมน้อยที่สุด (เพียงตรวจสอบความแตกต่างในPATHเป็นตัวอย่าง)


15
นอกจากนี้ยังมีค่าชี้ให้เห็นว่าเป็นความแตกต่างกับ cron ก็คือการatรักษาสภาพแวดล้อมของคุณเหมือนที่เคยเป็นงานที่กำหนด: ไดเรกทอรีการทำงานเดียวกันตัวแปรสภาพแวดล้อม ...
Carlos Campderrós

10
นอกจากนี้ยังมีbatchซึ่งเกือบจะเหมือนกันatแต่จะรอให้โหลดต่ำแทนและเห็นได้ชัดว่าat -q zจะดีงานด้วยตัวเองในขณะที่at -q Zจะรอเวลาจากนั้นรอให้โหลดที่จะลดลงและเป็นงานที่ดี ว้าวมันเป็นคุณสมบัติที่ใช้บ่อยมาก!
Ulrich Schwarz

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 ( at, atq, atrmและbatch) คุณใช้atและbatchกำหนดเวลางานatqเพื่อดูว่ามีกำหนดเวลาอะไรและatrmเพื่อลบงานก่อนที่จะทำงาน

$ at -f <cmd> timspec

Timespec

เวลาในการเรียกใช้atงานสามารถระบุได้หลายวิธี

ข้อความที่ตัดตอนมาที่หน้าคน

ที่อนุญาตให้มีข้อกำหนดเวลาค่อนข้างซับซ้อนขยายมาตรฐาน POSIX.2 ยอมรับเวลาในรูปแบบ HH: MM เพื่อทำงานในเวลาที่กำหนดของวัน (หากเวลานั้นผ่านไปแล้ววันถัดไปจะถูกสันนิษฐาน) นอกจากนี้คุณยังสามารถระบุเที่ยงคืนเที่ยงหรือ teatime (4:00 น.) และคุณสามารถมีเวลาต่อวันด้วย AM หรือ PM สำหรับการทำงานในตอนเช้า หรือตอนเย็น คุณสามารถพูดได้ว่าวันใดที่จะทำงานโดยให้วันที่ในรูปแบบชื่อเดือนกับปีที่เลือกหรือให้วันที่ของแบบฟอร์ม MMDD [CC] YY, MM / DD / [CC] YY, DD.MM. [CC] YY หรือ [CC] YY-MM-DD สเปคของวันที่จะต้องเป็นไปตามสเปคของเวลาของวัน นอกจากนี้คุณยังสามารถให้เวลาเช่นตอนนี้ + นับเวลาหน่วยซึ่งเวลา - หน่วยสามารถเป็นนาทีชั่วโมงวัน

ตัวอย่าง

สมมติว่าคุณมีเชลล์สคริปต์นี้

$ 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

อ้างอิง


ฉันดูเหมือนจะมีเวอร์ชันที่แตกต่างกันมากatในการติดตั้ง Cygwin ของฉัน - ดูเหมือนจะไม่เชื่อมโยงกับbatchไม่มีตัวเลือกสั้น ๆ ที่ได้รับการสนับสนุนไม่มีตัวเลือกที่เงียบและไม่มีmanหรือinfoรวมหน้าเว็บด้วย
Hashim

@Hashim - cygwin เป็นสัตว์ของตัวเอง
slm

6

คุณสามารถทำงานแบ็ตช์ใน UNIX / Linux โดยใช้หนึ่งในสามคำสั่ง - ที่, แบทช์หรือ cron

กำหนดเวลางานโดยใช้วันที่และเวลาที่ระบุ

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

ใช่ฉันเข้าใจว่า "ที่" และการใช้งาน คนอื่น ๆ ตอบว่ามันมีความเกี่ยวข้องมากกว่า
Akshay Patil

5

ผู้ดูแลระบบเครือข่ายของคุณแจ้งให้คุณทราบว่าการบำรุงรักษาบางอย่างจะเกิดขึ้นกับเว็บเซิร์ฟเวอร์ของคุณเริ่มตั้งแต่เวลา 19.00 น. และสิ้นสุดในเวลาตีสอง คุณต้องการที่จะให้บริการการแจ้งเตือนการบำรุงรักษาล่วงหน้าและคุณต้องการ uptime สูงสุดจากระบบของคุณ คุณจะอยู่ทั้งคืนพร้อมที่จะใช้คำสั่งต่าง ๆ แล้วเริ่มต้นขึ้นอีกครั้งในภายหลัง? ไม่คุณต้องการใช้atกำหนดเวลางานเหล่านี้จากนั้นเข้านอน / เล่น skyrim และลืมมันไป


1

atยังสามารถเป็นวิธีที่มีประโยชน์จริงๆในการปิดการแจ้งเตือน เครื่อง dev ปัจจุบันของฉันใช้งาน 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.