Тестування робочих записів на тиждень [закрито]


237

У мене є #!/bin/bashфайл у каталозі cron.week.

Чи є спосіб перевірити, чи працює він? Не можу чекати 1 тиждень

Я на Debian 6 з root


4
Ви не можете просто перевірити скрипт, запустивши його в командному рядку?
Фредерік Хаміді

5
просто додайте окремий запис у свій crontabфайл, який запускає ваш файл кожні кілька хвилин, подивіться, чи є очікувані результати, а потім видаліть тестовий запис зі свого кронтабуля. спробуватиcrontab -e
davin

61
Ні, запустити його з командного рядка - це не гарний спосіб. Щойно запуск сценарію з командного рядка не гарантує, що він навіть запуститься, як той самий користувач, коли запускався з cron. Навіть якщо він запускається як той самий користувач, ви ніколи не можете бути впевнені, чи все інше буде таким же. Сценарії, робота з командного рядка , може не для всіх видів причин при запуску з хрон.
andynormancx

8
"всі види" можуть бути злегка гіперболічними ... дозволи та змінні середовища - це два, які виникають на увазі, ви могли легко мати інші інші початкові умови, як псевдоніми, хоча
andynormancx

3
Я щойно переживав тестування нової роботи з крон, додам ще один пункт до "всіляких". Якщо у вас є речі в bash_profile, вони не запускаються один раз у роботі cron, тоді як тестування завдання з командного рядка працює бездоганно. Тестування завдань cron у стандартному командному рядку зовсім не є хорошим тестом.
andynormancx

Відповіді:


233

Просто робіть те, що робить cron, виконайте наступне root:

run-parts -v /etc/cron.weekly

... або наступний, якщо ви отримаєте помилку "Не каталог: -v":

run-parts /etc/cron.weekly -v

Опція -vдрукує імена сценарію перед їх запуском.


4
Якщо я використовую опцію -v, вона відображає помилку "Не каталог: -v", для цієї команди в моїй системі немає сторінки "man", -v означає багатослівний прав? Я використовую centos 6.4
макс

3
Щоб уникнути помилки "Не каталог", я повинен був зробити це замість цього: run-parts /etc/cron.weekly -v
Craig Hyatt

22
Але це не враховує змінні середовища, які можна встановити в crontab
fcurella

34
run-partsпросто запускає сценарії заданого каталогу. Нічого спільного з кроном.
Ніколя

23
Це дійсно не повинно було бути прийнятим і прийнятим, окрім запуску сценарію, це нічого не говорить про те, чи справді скрипт буде працювати при запуску з cron. Скористайтеся чудовим сценарієм Crontest в одній з інших відповідей на це питання.
andynormancx

87

Трохи поза рамками вашого питання ... але ось що я роблю.

"Як я перевіряю роботу з кроном?" питання тісно пов'язане з "як я тестую сценарії, які виконуються в неінтерактивних контекстах, запущених іншими програмами?" У cron тригер є певним часом, але багато інших * nix-інструментів запускають скрипти або фрагменти сценарію неінтерактивними способами, і часто умови, в яких ці сценарії запущені, містять щось несподіване і викликають поломку, поки помилки не розібрані. (Дивіться також: https://stackoverflow.com/a/17805088/237059 )

Корисний загальний підхід до цієї проблеми.

Один з моїх улюблених прийомів - це використання сценарію, який я написав під назвою « crontest ». Він запускає цільову команду всередині сеансу екрана GNU зсередини cron, так що ви можете приєднатись до окремого терміналу, щоб побачити, що відбувається, взаємодіяти зі сценарієм і навіть використовувати відладчик.

Щоб налаштувати це, ви використовуєте "всі зірки" у своєму записі crontab і вказуєте crontest як першу команду в командному рядку, наприклад:

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

Отже, тепер cron буде виконувати вашу команду щохвилини, але crontest забезпечить запуск лише одного екземпляра. Якщо команді потрібен час для запуску, ви можете зробити "screen -x", щоб прикріпити та спостерігати за її виконанням. Якщо команда є сценарієм, ви можете поставити команду "прочитати" вгорі, щоб зупинити її і дочекатися завершення вкладення екрана (натисніть Enter після вкладення)

Якщо ваша команда є скриптом bash, ви можете зробити це замість цього:

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

Тепер, якщо ви додасте "screen -x", вам доведеться зіткнутися з інтерактивним сеансом bashdb, і ви зможете перейти через код, вивчити змінні тощо.

#!/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
Дивовижне, ідеальне рішення. Всі інші методи, які я спробував, насправді не спрацювали, crontest вирішив проблему легко.
andynormancx

1
Це було набагато більше, ніж мені потрібно, але +1 все одно для чудового рішення; встановлення cron для запуску частіше і скидання виводу в / tmp було досить добре, щоб помітити мою проблему.
jcollum

2
Класно. Так, немає причин стріляти з бульдозера, якщо вам просто потрібна ручна лопата :)
Stabledog

2
Чудові речі. Зверніть увагу на mac, я повинен brew tap discoteq/discoteq; brew install flockбув змінити сценарій для використання/usr/local/bin/flock
Claudiu

1
приємна утиліта! Дуже корисно діагностувати проблеми аутентифікації в неінтерактивних контекстах.
Ерік Блюм

44

Після возитися з деякими речами в cron, які не були миттєво сумісні, я виявив, що наступний підхід підходить для налагодження:

crontab -e

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

Це запустить завдання раз на хвилину, і ви можете просто подивитися у /tmp/cron_debug_log.logфайлі, щоб зрозуміти, що відбувається.

Ви, можливо, не саме "пожежна робота", яку ви шукали, але це мені дуже допомогло при налагодженні сценарію, який спочатку не працював у cron.


9
Я рекомендував би такий підхід. Проблема в більшості випадків полягає в тому, що ви не бачите помилки.
Яуген Якимович

8
Неправильна лінія, не будь-який розподіл використовує bash для оболонки cron, і так & >> не працює. Я пропоную використовувати >>/tmp/cron_debug_log.log 2>&1Замість цього
drizzt

1
Що ти маєш на увазі під /path/to/progяким прогром?
Натан

3
Програма, яку ви збираєтеся запускати з cron. Це може бути usr/home/myFancyScript.shабо просто ls, або все, що ви хочете регулярно бігати.
Automatico

Це працювало для мене. Це був найпростіший метод зробити швидкий тест, щоб перевірити, чи все добре
abhijit

25

Я б застосував файл блокування, а потім встановив роботу cron, щоб запускатися щохвилини. (використовуйте crontab -e та * * * * * / шлях / до / робота) Таким чином, ви можете просто продовжувати редагування файлів і щохвилини вони будуть перевірені. Крім того, ви можете зупинити cronjob, просто торкнувшись файлу блокування.

    #!/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
Ви також можете використовувати flock(1)з оболонки; див man 1 flock. Досить зручно для таких застосувань, оскільки забезпечує автоматичне блокування.
Крейг Рінгер

5

А як із тим, щоб його вкласти cron.hourly, чекати до наступного запуску погодинних завдань, а потім видалити його? Це запустило б його один раз протягом години та в середовищі cron. Ви також можете запустити ./your_script, але це не матиме таке ж середовище, як під cron.


це майже те саме, що відповідь @ Cort3z, з меншими деталями
jcollum

5

Жоден із цих відповідей не відповідав моїй конкретній ситуації, яка полягала в тому, що я хотів запустити одну конкретну роботу з крон, лише один раз, і запустити її негайно.

Я на сервері Ubuntu, і я використовую cPanel для налаштування моїх задач cron.

Я просто записав свої поточні налаштування, а потім відредагував їх, щоб вони були зараз хвилиною. Коли я виправив ще одну помилку, я просто відредагував її знову за одну хвилину. І коли я все закінчив, я просто повернув налаштування до того, як вони були раніше.

Приклад: зараз 16:34 вечора, тому я поставив 35 16 * * *, щоб він працював о 16:35.

Це спрацювало як шарм, і найбільше мені довелося почекати - це трохи менше однієї хвилини.

Я подумав, що це кращий варіант, ніж деякі інші відповіді, тому що я не хотів запускати всі свої тижневі крони, і я не хотів, щоб робота працювала щохвилини. Щоб виправити будь-які проблеми, перш ніж я готовий перевірити її, потрібно кілька хвилин. Сподіваємось, це комусь допомагає.


Чому б ви використовували cron, щоб запустити "лише один раз і запустити його негайно"? Здається, вам буде краще просто запустити сценарій безпосередньо.
Ян Хантер

4

Крім цього, ви також можете використовувати:

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

щоб завершити ваш крон, щоб надіслати вам електронний лист після успіху чи відмови.


10
Чи Cron вже не надсилає електронну пошту та виводить із сценарію після його виконання?
Ерік

Cron надсилає електронну пошту користувачеві, і, як правило, користувач для більшості завдань cron - це або root, або користувач не інтерактивного сервісу, тому ви ніколи не бачите електронних листів. Ось як сервери заповнюються, коли помилка викликає величезну повінь електронних листів, і вони відскакують на корінь.
dragon788

3

Я використовую таке рішення:

  1. Редагуйте crontab (використовуйте команду: crontab -e), щоб виконувати завдання так часто, як це потрібно (кожні 1 хвилину або 5 хвилин)
  2. Змініть скрипт оболонки, який повинен бути виконаний за допомогою cron для друку виводу в якийсь файл (наприклад: echo "Працює нормально" >>
    output.txt)
  3. Перевірте файл output.txt за допомогою команди: tail -f output.txt, яка надрукує останні файли в цей файл, і, таким чином, ви можете відстежувати виконання сценарію

2

Я зазвичай тестую, виконуючи роботу, яку я створив так:

Для цього простіше використовувати два термінали.

запустити роботу:

#./jobname.sh

йти до:

#/var/log and run 

запустіть наступне:

#tailf /var/log/cron

Це дозволяє мені бачити оновлення журналів cron в режимі реального часу. Ви також можете переглянути журнал після його запуску, я вважаю за краще дивитися в режимі реального часу.

Ось приклад простої роботи з крон. Запуск оновленого оновлення ...

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

Ось поділка:

Перша команда оновить yum сама, а наступна застосує оновлення системи.

-R 120: Встановлює максимальну кількість часу, яку ви будете чекати перед виконанням команди

-e 0: Встановлює рівень помилки на 0 (діапазон 0 - 10). 0 означає друкувати лише критичні помилки, про які вам потрібно повідомити.

-d 0: Встановлює рівень налагодження на 0 - збільшує або зменшує кількість надрукованих речей. (діапазон: 0 - 10).

-y: Припустимо, так; припустимо, що відповідь на будь-яке запитання, яке було б задано, - так

Після того, як я побудував роботу cron, я запустив команду нижче, щоб зробити свою роботу виконуваною.

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

Сподіваюся, це допоможе, Дорлак


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

Файли в цьому crontabs/каталозі повинні виконуватись власником - восьмериками700

джерело: man cronі NNRooth's


5
Два тинг. По-перше: для запуску речей як sudo використовується інше середовище (визначені змінні). Отже, вади у вашій crontab можуть працювати, коли виконуються як "sudo", але не працюватимуть як "root" (і навпаки). По-друге: "man cron" не показує мені цю інформацію (нормально, моя людина, здається, специфічна для debian) ... "man run-parts" каже, що --test не запускає сценарії, а лише друкує імена їх. Тож сценарії навіть не перевірені. Незначна річ: "виконується власником": Наскільки я знаю, кроніо виконуються лише як root.
Алекс

-1

Я використовую Webmin, оскільки його дорогоцінний камінь продуктивності для тих, хто вважає адміністрування командного рядка трохи загрозливим і непроникним.

У веб-інтерфейсі "Система> Заплановані завдання Cron> Редагувати роботу Cron" є кнопка "Зберегти та запустити зараз".

Він відображає вихід команди і саме те, що мені було потрібно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.