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


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.