Kiểm tra một công việc định kỳ hàng tuần [đóng]


237

Tôi có một #!/bin/bashtập tin trong thư mục cron.week.

Có cách nào để kiểm tra nếu nó hoạt động? Không thể đợi 1 tuần

Tôi đang dùng Debian 6 với root


4
Bạn có thể kiểm tra tập lệnh bằng cách chạy nó trên dòng lệnh không?
Frédéric Hamidi

5
chỉ cần thêm một mục riêng trong crontabtệp chạy tệp của bạn cứ sau vài phút, xem kết quả mong đợi có ở đó không, rồi xóa mục kiểm tra khỏi crontab của bạn. thửcrontab -e
davin

61
Không, chạy nó từ dòng lệnh không phải là một cách tốt. Chỉ chạy tập lệnh từ dòng lệnh không đảm bảo nó thậm chí sẽ chạy như cùng một người dùng khi chạy từ cron. Ngay cả khi nó được chạy như một người dùng, bạn không bao giờ có thể chắc chắn liệu mọi thứ khác có giống nhau không. Các tập lệnh hoạt động từ dòng lệnh có thể thất bại vì mọi lý do khi chạy từ cron.
andynormancx

8
"tất cả các loại" có thể hơi cường điệu ... các quyền và biến môi trường là hai yếu tố nảy sinh trong tâm trí, bạn có thể dễ dàng có các điều kiện ban đầu khác như bí danh
andynormancx

3
Tôi vừa trải qua thử nghiệm một công việc định kỳ mới, tôi sẽ thêm một mục khác vào "tất cả các loại". Nếu bạn có những thứ trong bash_profile, chúng sẽ không được chạy một lần trong công việc định kỳ, trong khi đó việc kiểm tra công việc từ dòng lệnh hoạt động hoàn hảo. Kiểm tra các công việc định kỳ trên dòng lệnh tiêu chuẩn hoàn toàn không phải là một thử nghiệm tốt.
andynormancx

Câu trả lời:


233

Chỉ cần làm những gì cron làm, chạy như sau root:

run-parts -v /etc/cron.weekly

... hoặc cái tiếp theo nếu bạn nhận được lỗi "Không phải là thư mục: -v":

run-parts /etc/cron.weekly -v

Tùy chọn -vin tên tập lệnh trước khi chúng được chạy.


4
Nếu tôi sử dụng tùy chọn -v thì nó hiển thị lỗi "Không phải là thư mục: -v", không có trang man nào cho lệnh này trong hệ thống của tôi, -v có nghĩa là dài dòng phải không? Tôi đang sử dụng centos 6.4
tối đa

3
Để tránh lỗi "Không phải thư mục", tôi đã phải thực hiện việc này thay vào đó: run-tùng /etc/cron.weekly -v
Craig Hyatt

22
Nhưng điều này không tính đến các biến môi trường có thể được đặt trong crontab
fcurella

34
run-partschỉ chạy các kịch bản của một thư mục nhất định. Không có gì để làm với cron.
Nicolas

23
Điều này thực sự không nên được nâng cấp và chấp nhận, ngoài việc chạy tập lệnh, không có gì để cho bạn biết liệu tập lệnh có thực sự hoạt động khi chạy từ cron hay không. Sử dụng kịch bản crontest xuất sắc trong một trong những câu trả lời khác cho câu hỏi này.
andynormancx

87

Một chút ngoài phạm vi câu hỏi của bạn ... nhưng đây là những gì tôi làm.

"Làm thế nào để tôi kiểm tra một công việc định kỳ?" câu hỏi được kết nối chặt chẽ với "làm cách nào để kiểm tra các tập lệnh chạy trong bối cảnh không tương tác được khởi chạy bởi các chương trình khác?" Trong cron, trình kích hoạt là một số điều kiện thời gian, nhưng rất nhiều cơ sở * nix khác khởi chạy các tập lệnh hoặc đoạn mã theo cách không tương tác và thường là các điều kiện trong đó các tập lệnh chạy có chứa điều gì đó bất ngờ và gây ra vỡ cho đến khi các lỗi được sắp xếp. (Xem thêm: https://stackoverflow.com/a/17805088/237059 )

Một cách tiếp cận chung cho vấn đề này là hữu ích để có.

Một trong những kỹ thuật yêu thích của tôi là sử dụng một kịch bản mà tôi đã viết có tên là ' crontest '. Nó khởi chạy lệnh đích bên trong phiên màn hình GNU từ bên trong cron, để bạn có thể đính kèm với một thiết bị đầu cuối riêng biệt để xem những gì đang diễn ra, tương tác với tập lệnh, thậm chí sử dụng trình gỡ lỗi.

Để thiết lập tính năng này, bạn sẽ sử dụng "tất cả các ngôi sao" trong mục nhập crontab của mình và chỉ định crontest là lệnh đầu tiên trên dòng lệnh, ví dụ:

* * * * * crontest /command/to/be/tested --param1 --param2

Vì vậy, bây giờ cron sẽ chạy lệnh của bạn mỗi phút, nhưng crontest sẽ đảm bảo rằng chỉ có một phiên bản chạy tại một thời điểm. Nếu lệnh mất thời gian để chạy, bạn có thể thực hiện "màn hình -x" để đính kèm và xem nó chạy. Nếu lệnh là một tập lệnh, bạn có thể đặt lệnh "đọc" ở trên cùng để làm cho nó dừng lại và chờ cho phần đính kèm màn hình hoàn tất (nhấn enter sau khi đính kèm)

Nếu lệnh của bạn là tập lệnh bash, bạn có thể thực hiện việc này thay thế:

* * * * * crontest --bashdb /command/to/be/tested --param1 --param2

Bây giờ, nếu bạn đính kèm với "screen -x", bạn sẽ phải đối mặt với phiên bashdb tương tác và bạn có thể bước qua mã, kiểm tra các biến, v.v.

#!/bin/bash

# crontest
# See https://github.com/Stabledog/crontest for canonical source.

# Test wrapper for cron tasks.  The suggested use is:
#
#  1. When adding your cron job, use all 5 stars to make it run every minute
#  2. Wrap the command in crontest
#        
#
#  Example:
#
#  $ crontab -e
#     * * * * * /usr/local/bin/crontest $HOME/bin/my-new-script --myparams
#
#  Now, cron will run your job every minute, but crontest will only allow one
#  instance to run at a time.  
#
#  crontest always wraps the command in "screen -d -m" if possible, so you can
#  use "screen -x" to attach and interact with the job.   
#
#  If --bashdb is used, the command line will be passed to bashdb.  Thus you
#  can attach with "screen -x" and debug the remaining command in context.
#
#  NOTES:
#   - crontest can be used in other contexts, it doesn't have to be a cron job.
#       Any place where commands are invoked without an interactive terminal and
#       may need to be debugged.
#
#   - crontest writes its own stuff to /tmp/crontest.log
#
#   - If GNU screen isn't available, neither is --bashdb
#

crontestLog=/tmp/crontest.log
lockfile=$(if [[ -d /var/lock ]]; then echo /var/lock/crontest.lock; else echo /tmp/crontest.lock; fi )
useBashdb=false
useScreen=$( if which screen &>/dev/null; then echo true; else echo false; fi )
innerArgs="$@"
screenBin=$(which screen 2>/dev/null)

function errExit {
    echo "[-err-] $@" | tee -a $crontestLog >&2
}

function log {
    echo "[-stat-] $@" >> $crontestLog
}

function parseArgs {
    while [[ ! -z $1 ]]; do
        case $1 in
            --bashdb)
                if ! $useScreen; then
                    errExit "--bashdb invalid in crontest because GNU screen not installed"
                fi
                if ! which bashdb &>/dev/null; then
                    errExit "--bashdb invalid in crontest: no bashdb on the PATH"
                fi

                useBashdb=true
                ;;
            --)
                shift
                innerArgs="$@"
                return 0
                ;;
            *)
                innerArgs="$@"
                return 0
                ;;
        esac
        shift
    done
}

if [[ -z  $sourceMe ]]; then
    # Lock the lockfile (no, we do not wish to follow the standard
    # advice of wrapping this in a subshell!)
    exec 9>$lockfile
    flock -n 9 || exit 1

    # Zap any old log data:
    [[ -f $crontestLog ]] && rm -f $crontestLog

    parseArgs "$@"

    log "crontest starting at $(date)"
    log "Raw command line: $@"
    log "Inner args: $@"
    log "screenBin: $screenBin"
    log "useBashdb: $( if $useBashdb; then echo YES; else echo no; fi )"
    log "useScreen: $( if $useScreen; then echo YES; else echo no; fi )"

    # Were building a command line.
    cmdline=""

    # If screen is available, put the task inside a pseudo-terminal
    # owned by screen.  That allows the developer to do a "screen -x" to
    # interact with the running command:
    if $useScreen; then
        cmdline="$screenBin -D -m "
    fi

    # If bashdb is installed and --bashdb is specified on the command line,
    # pass the command to bashdb.  This allows the developer to do a "screen -x" to
    # interactively debug a bash shell script:
    if $useBashdb; then
        cmdline="$cmdline $(which bashdb) "
    fi

    # Finally, append the target command and params:
    cmdline="$cmdline $innerArgs"

    log "cmdline: $cmdline"


    # And run the whole schlock:
    $cmdline 

    res=$?

    log "Command result: $res"


    echo "[-result-] $(if [[ $res -eq 0 ]]; then echo ok; else echo fail; fi)" >> $crontestLog

    # Release the lock:
    9<&-
fi

2
Tuyệt vời, giải pháp hoàn hảo. Tất cả các kỹ thuật khác mà tôi đã thử không thực sự hiệu quả, đã giải quyết vấn đề một cách dễ dàng.
andynormancx

1
Đây là cách nhiều hơn tôi cần nhưng +1 cho một giải pháp tuyệt vời nào; thiết lập cron để chạy thường xuyên hơn và chuyển đầu ra thành / tmp là đủ tốt để phát hiện ra vấn đề của tôi.
jcollum

2
Mát mẻ. Vâng, không có lý do gì để kích hoạt máy ủi nếu bạn chỉ cần một cái thuổng tay :)
Stablesog 17/8/2016

2
Công cụ tuyệt vời. Lưu ý trên mac Tôi đã phải brew tap discoteq/discoteq; brew install flockvà sau đó sửa đổi tập lệnh để sử dụng/usr/local/bin/flock
Claudiu

1
tiện ích tốt đẹp! Rất hữu ích để chẩn đoán các vấn đề xác thực trong bối cảnh không tương tác.
Eric Blum

44

Sau khi tìm hiểu về một số nội dung trong cron không tương thích ngay lập tức, tôi thấy rằng cách tiếp cận sau đây là tốt để gỡ lỗi:

crontab -e

* * * * * /path/to/prog var1 var2 &>>/tmp/cron_debug_log.log

Điều này sẽ chạy nhiệm vụ một lần một phút và bạn có thể chỉ cần nhìn vào /tmp/cron_debug_log.logtệp để tìm hiểu những gì đang xảy ra.

Nó không chính xác là "công việc lửa" mà bạn có thể đang tìm kiếm, nhưng điều này đã giúp tôi rất nhiều khi gỡ lỗi một kịch bản không hoạt động trong cron lúc đầu.


9
Tôi muốn giới thiệu phương pháp này. Vấn đề trong hầu hết các trường hợp là bạn không thấy lỗi.
Yauhen Yakimovich

8
Dòng không chính xác, không phải bất kỳ phân phối nào sử dụng bash cho cron shell và vì vậy & >> không hoạt động. Tôi đề nghị sử dụng >>/tmp/cron_debug_log.log 2>&1Thay vào đó
mưa phùn

1
Bạn có ý nghĩa gì bởi /path/to/prog- prog nào?
Nathan

3
Chương trình bạn sẽ chạy với cron. Điều này có thể usr/home/myFancyScript.shhoặc nó có thể là một đơn giản ls, hoặc bất cứ điều gì bạn muốn chạy thường xuyên.
Automatico

Điều này làm việc cho tôi. Đó là phương pháp dễ nhất để làm một bài kiểm tra nhanh để kiểm tra xem mọi thứ có ổn không
abhijit

25

Tôi sẽ sử dụng tệp khóa và sau đó đặt công việc định kỳ để chạy mỗi phút. (sử dụng crontab -e và * * * * * / path / to / job) Bằng cách đó, bạn có thể tiếp tục chỉnh sửa các tệp và mỗi phút chúng sẽ được kiểm tra. Ngoài ra, bạn có thể dừng cronjob bằng cách chạm vào tệp khóa.

    #!/bin/sh
    if [ -e /tmp/cronlock ]
    then
        echo "cronjob locked"
        exit 1
    fi

    touch /tmp/cronlock
    <...do your regular cron here ....>
    rm -f /tmp/cronlock

4
Bạn cũng có thể sử dụng flock(1)từ vỏ; thấy man 1 flock. Khá tiện cho việc sử dụng như vậy vì nó cung cấp tính năng chặn tự động.
Craig Ringer

5

Điều gì về việc đưa nó vào cron.hourly, chờ đợi cho đến khi các công việc định kỳ hàng giờ tiếp theo, sau đó loại bỏ nó? Điều đó sẽ chạy nó một lần trong vòng một giờ và trong môi trường định kỳ. Bạn cũng có thể chạy ./your_script, nhưng điều đó sẽ không có môi trường giống như dưới cron.


điều này khá giống với câu trả lời của @ Cort3z, với ít chi tiết hơn
jcollum

5

Không có câu trả lời nào phù hợp với tình huống cụ thể của tôi, đó là tôi muốn chạy một công việc định kỳ cụ thể, chỉ một lần và chạy nó ngay lập tức.

Tôi đang sử dụng máy chủ Ubuntu và tôi sử dụng cPanel để thiết lập các công việc định kỳ của mình.

Tôi chỉ đơn giản là viết ra các thiết lập hiện tại của mình, và sau đó chỉnh sửa chúng thành một phút kể từ bây giờ. Khi tôi sửa một lỗi khác, tôi chỉ cần chỉnh sửa lại một phút nữa. Và khi tôi đã hoàn tất, tôi chỉ cần đặt lại cài đặt về trạng thái trước đó.

Ví dụ: Bây giờ là 4:34 chiều, vì vậy tôi đặt 35 16 * * *, để nó chạy lúc 16:35.

Nó hoạt động như một bùa mê, và điều tôi từng chờ đợi nhất là ít hơn một phút.

Tôi nghĩ rằng đây là một lựa chọn tốt hơn so với một số câu trả lời khác bởi vì tôi không muốn chạy tất cả các crons hàng tuần của mình và tôi không muốn công việc chạy mỗi phút. Tôi phải mất vài phút để khắc phục mọi sự cố trước khi tôi sẵn sàng kiểm tra lại. Hy vọng điều này sẽ giúp được ai đó.


Tại sao bạn lại sử dụng cron để chạy "chỉ một lần và chạy ngay lập tức"? Có vẻ như bạn sẽ tốt hơn nếu chỉ chạy tập lệnh trực tiếp.
Ian Hunter

4

Ngoài ra, bạn cũng có thể sử dụng:

http://pypi.python.org/pypi/cronwrap

để kết thúc cron của bạn để gửi email cho bạn khi thành công hay thất bại.


10
Không phải Cron đã gửi email và xuất ra từ tập lệnh khi thực thi?
Erik

Cron gửi email cho người dùng và thông thường người dùng cho hầu hết các công việc cron là người dùng gốc hoặc dịch vụ không tương tác, do đó bạn không bao giờ thấy email. Đây là cách các máy chủ được lấp đầy khi một lỗi gây ra một lũ email khổng lồ và chúng bị trả về root.
dragon788

3

Giải pháp tôi đang sử dụng như sau:

  1. Chỉnh sửa crontab (sử dụng lệnh: crontab -e) để chạy công việc thường xuyên khi cần thiết (cứ sau 1 phút hoặc 5 phút)
  2. Sửa đổi tập lệnh shell cần được thực thi bằng cron để in đầu ra thành một số tệp (ví dụ: echo "Hoạt động tốt" >>
    output.txt)
  3. Kiểm tra tệp output.txt bằng lệnh: tail -f output.txt, phần này sẽ in các bổ sung mới nhất vào tệp này và do đó bạn có thể theo dõi việc thực thi tập lệnh

2

Tôi thường kiểm tra bằng cách chạy công việc tôi đã tạo như thế này:

Nó dễ dàng hơn để sử dụng hai thiết bị đầu cuối để làm điều này.

điều hành công việc:

#./jobname.sh

đi đến:

#/var/log and run 

chạy như sau:

#tailf /var/log/cron

Điều này cho phép tôi xem cập nhật nhật ký cron trong thời gian thực. Bạn cũng có thể xem lại nhật ký sau khi bạn chạy nó, tôi thích xem trong thời gian thực.

Dưới đây là một ví dụ về một công việc cron đơn giản. Chạy bản cập nhật yum ...

#!/bin/bash
YUM=/usr/bin/yum
$YUM -y -R 120 -d 0 -e 0 update yum
$YUM -y -R 10 -e 0 -d 0 update

Đây là sự cố:

Lệnh đầu tiên sẽ tự cập nhật yum và tiếp theo sẽ áp dụng các cập nhật hệ thống.

-R 120: Đặt lượng thời gian tối đa yum sẽ đợi trước khi thực hiện lệnh

-e 0: Đặt mức lỗi thành 0 (phạm vi 0 - 10). 0 có nghĩa là chỉ in các lỗi nghiêm trọng mà bạn phải được thông báo.

-d 0: Đặt mức gỡ lỗi thành 0 - tăng hoặc giảm số lượng những thứ được in. (phạm vi: 0 - 10).

-y: Giả sử có; giả sử rằng câu trả lời cho bất kỳ câu hỏi nào sẽ được hỏi là có

Sau khi tôi xây dựng công việc định kỳ, tôi chạy lệnh bên dưới để thực hiện công việc của mình.

#chmod +x /etc/cron.daily/jobname.sh 

Hy vọng điều này sẽ giúp, Dorlack


2
sudo run-parts --test /var/spool/cron/crontabs/

các tập tin trong crontabs/thư mục đó cần được thực thi bởi chủ sở hữu - bát phân700

nguồn: man cronNNRoothcủa


5
Hai tings. Đầu tiên: Để chạy mọi thứ như sudo sử dụng một môi trường khác (các biến được xác định). Vì vậy, các lỗi trong crontab của bạn có thể hoạt động khi được thực thi dưới dạng 'sudo', nhưng sẽ không hoạt động khi được thực thi dưới dạng 'root' (và ngược lại). Thứ hai: 'man cron' không hiển thị cho tôi thông tin này (ok, người đàn ông của tôi dường như là người đặc biệt của debian) ... họ Vì vậy, các kịch bản thậm chí không được thử nghiệm. Một điều nhỏ: 'thực thi bởi chủ sở hữu': Theo như tôi biết, cronjobs chỉ được thực thi dưới quyền root.
Alex

-1

Tôi đang sử dụng Webmin vì đây là viên ngọc năng suất cho một người tìm thấy quản trị dòng lệnh hơi khó xử và không thể xuyên thủng.

Có nút "Lưu và chạy ngay" trong giao diện web "Hệ thống> Công việc định kỳ theo lịch> Chỉnh sửa công việc định kỳ".

Nó hiển thị đầu ra của lệnh và chính xác là những gì tôi cần.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.