Перейти к содержимому
Калькуляторы

Странности с планировщиком (Debian Linux, cron)

Есть у меня несколько сервисных скриптов.

Например такой:

#!/usr/bin/php -q
<?php

if (php_sapi_name() != 'cli') die("Jobs allowed from shell (cli) only\n");

include("../lib/header.php");

$bm = Billing::getInstance();
$agents = $bm->select('PAYMENT_AGENT', 'ID', null, array('ID'=>'PAYMENT_AGENT_ID', 'CLASS', 'CODE', 'NAME', 'TRADENAME', 'TZ'));
$checks = $bm->select('PAYMENT_AGENT_TRANSPORT', null, array('TRANSPORT'=>'email'));

$email = TransportFactory::create('email');
$email->onRecv('processing');
$email->recv();
unset($email);

function processing($request)
{
   echo "Get request, from <" . $request->from . ">\n";
   ...
}

 

Скрипт проверяет электронную почту, обрабатывает письма и после шлет мне на email отчет по обработке. В процессе обработки выводит в консоль различную информацию.

Если запускать скрипт интерактивно, то он всегда отрабатывает нормально, хоть из под root, хоть из под пользователя.

 

Скрипт запускается по расписанию.

В планировщик добавлена такая строчка:

5 * * * * user1 cd /jobs/job1 && ./job1.sh  >> output.log 2>&1

И к нему скрипт-обертка /jobs/job1/job1.sh для запуска:

#!/bin/sh

echo "Call job1, `date`..."
cd /tools/php
/usr/bin/php -q job1.php

 

Работу скрипта я вижу по приходящим на электронную почту отчетам.

Какое-то время скрипт нормально запускается из планировщика, результаты выполнения выводятся в файл output.log.

Но потом в какой-то момент скрипт перестает работать.

Если просмотреть файл output.log, то в нем последней строкой будет что-то такое:

Call job1, Thu Apr 16 21:12:52 MSK 2015
Get request, fro

 

Что это может быть?

Почему вывод в файл может обрываться на середине слова?

Если «поломался» PHP-скрипт, то почему в файле output.log нет вывода из скрипта-обертки, который выводит «Call job1»?

Если файл output.log просто удалить, то работа скрипта возобновляется. На какое-то время, а затем снова проблема повторяется.

Никто с таким не сталкивался?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

может logrotate настроен на ваш output.log?

это веду к тому, что может что-то с правами

Изменено пользователем BETEPAH

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Бывают обрывки вывода при падении в корку. Как вариант, скрипт натыкается на письмо с какими-нибдуь "неправильными" символами внутри, и подрывается на них. Проверьте обработку текста.

Изменено пользователем vop

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как вариант, скрипт натыкается на письмо с какими-нибдуь "неправильными" символами внутри, и подрывается на них.

Возможно, в электронной почте куча подобных ситуаций.

Но почему тогда не срабатывают следующие вызовы планировщика (через час)?

 

это веду к тому, что может что-то с правами

Права 644, владелец user1.

Для пробы я делал права 666, не помогало.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Возможно, в электронной почте куча подобных ситуаций.

 

Там ожет быть еще путаница с кодесетами... Но то уже такое.

 

Но почему тогда не срабатывают следующие вызовы планировщика (через час)?

 

Он насовсем перестает работать? Но вот это же должно хотя бы выводиться:

 

echo "Call job1, `date`..."

 

Если выводится, и при каждом запуске затыкается на выводе строки "fro", может, как раз, и первым в обработке и стоит "кривое" письмишко? Надо бы его глянуть, может что там ломано.

 

И еще вопросик - при обработке сообщений там все правильно устанавливается (блокировки и т.д.)? Может там с конкурентным доступом что-нибудь не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Он насовсем перестает работать? Но вот это же должно хотя бы выводиться:

Вот именно.

Как будто крон выключился.

Или как будто не хватает прав на добавление текста в output.log.

Но крон работает (другие задания выполняются) и права на файле 644 с владельцем user1.

 

Если выводится, и при каждом запуске затыкается на выводе строки "fro", может, как раз, и первым в обработке и стоит "кривое" письмишко?

Если скрипт запустить вручную, он это письмо обрабатывает нормально.

 

И еще вопросик - при обработке сообщений там все правильно устанавливается (блокировки и т.д.)?

«Там» это где? На сервере электронной почты?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Может скрипт слишком долго работает и крон его по таймауту прибивает? А из за такого прибивания буфер stdout нормально не сбрасывается в файл?

Попробуйте запускать скрипт через setsid и на конце &

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Может скрипт слишком долго работает и крон его по таймауту прибивает?

Может и так. У IMAP таймауты большие.

Правда это по идее не должно мешать повторному вызову.

 

Попробуйте запускать скрипт через setsid и на конце &

Через setsid запускать скрипт-обертку или PHP-скрипт?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Любопытная статистика накопилась.

Скорее всего дело вообще не в правах доступа.

 

Итак, в планировщик добавлена примерно такая строчка:

cd /jobs/job1 && ./job1.sh  >> output.log 2>&1

job1.sh это файл-обертка, в котором первой строчкой стоит команда date (выводит текущую дату/время), а второй запуск php или perl скрипта.

Какое-то время это задание успешно запускается, вывод дописывается в файл output.log.

Затем задание перестает работать, в output.log вывод обрывается на середине слова.

 

Если просто удалить файл output.log, то при следующем срабатывании планировщика в каталоге появляется пустой output.log.

Странность тут в том, что раз файл output.log создается, значит строка планировщика сработала.

А вдвойне странно то, что этот файл пустой — если уж sh-скрипт запустился, то хотя бы дату и время он должен был вывести.

Третья странность — какие-бы права доступа на этот файл я не задавал, хоть 666, скрипт не работает и вывод в output.log не добавляется.

Но если я интерактивно выполню такую команду (под любым пользователем, хоть user1, хоть root):

cd /jobs/job1 && ./job1.sh  >> output.log

(то есть после выполнения этой команды будет непустой файл output.log)

и затем для файла output.log пропишу права 666, то скрипт снова начинает работать какое-то время.

Такое впечатление, как будто при запуске строки из планировщика файл output.log создается какой-то неправильный и в него невозможно дописать данные.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если обрывается на полуслове, или вообще ничего не выводит, то, возможно, вылетает по сегментейшн фаулт. Сам крон по емейлу что пишет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

У меня когда-то была примерно такая же проблема: при интерактивном запуске отрабатывало, при запуске из крона - результат был непредсказуемый.

"Вылечилось" примерно такой крон-строкой:

 

02 05 * * * . /homeuser/.profile;/usr/bin/script

Изменено пользователем altnetwork.ru

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сам крон по емейлу что пишет?

Ничего. core-файлов тоже нигде не видно.

К тому же я ведь не рестартую crond. Я планировщик вообще не трогаю, но если я создаю файл output.log с содержимым, то задания начинают отрабатывать нормально.

 

"Вылечилось" примерно такой крон-строкой

А что это дает?

Мой user1 - это служебный пользователь, у которого нет home.

Просмотрел свой home - там только переменные окружения выставляются. А в рутовом - и того нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Уверен, что с буферизацией самого php разобрался?

ob_flush() и flush() в конце программы попробуй

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я где-то читал, что когда PHP запускается интерактивно (php_sapi_name()=='cli'), то он сам отключает буферизацию.

Но даже если это не так, я почти на 100% уверен, что причина не в буферизации.

Во-первых, такое же поведение наблюдается и для perl-скриптов, в которых я отключаю буферизацию ($|=1).

Во-вторых, это не объясняет, почему в файле output.log нет вывода команды date, которая указана в sh-файле перед запуском собственно скрипта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я бы для начала посмотрел логи php.

 

И уберите обертку, она не нужна.

Вывод в файл также не самый удачный подход для логирования.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я бы для начала посмотрел логи php.

А такое бывает?

Где их можно посмотреть?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я бы для начала посмотрел логи php.

А такое бывает?

Где их можно посмотреть?

 

сомнительно что бывает, а вот обертку можно и убрать и вызывать из под пхп date()

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

echo "Get request, from <" . $request->from . ">\n";

Возможно, проблема в неэкранированном знаке <, в процессе выполнения скрипта-обертки получается вызов

print abc < def > >> output.log

 

переделайте обертку на

#!/bin/sh
LOG="/jobs/job1/output.log"
echo "Call job1, `date`..." >> $LOG
cd /tools/php
/usr/bin/php -q job1.php >> $LOG

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А такое бывает?

Где их можно посмотреть?

Включите их в php.ini

error_log = /path/filename

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

есть подозрение, что крон запускает новое задание (скажем, в 10 минут), когда не закончилось выполнение предыдущего (запущенного, скажем, в 05 минут)

php-скрипт реентерабелен?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Планировщик запускается раз в час, скрипт выполняется в среднем менее минуты (иногда бывает дольше из-за больших таймаутов IMAP).

Параллельный запуск двух экземпляров по идее мешать не должен, там нет причин для взаимных блокировок.

 

Обертку переделаю, посмотрю как это повлияет.

Но сейчас уже третьи сутки задания выполняются нормально. Я пока ничего не менял.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Банально, но что-то не могу найти как отучить крон отправлять почту о результатах своей работы.

Задача в /cron.d/backup выглядит примерно так:

0 2     * * *     root     nice -n 15 mysqldump .... | gzip > "/tmp/lb_billing.`date +\%F`.sql.gz" ;  cd /tmp ; wput "lb_billing.`date +\%F`.sql.gz".... ; rm *.gz >/dev/null 2>&1

В /etc/crontab опцию MAILTO="" добавлял.

Все без толку.

ОС - Debian 9

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

6 minutes ago, Andrei said:

Банально, но что-то не могу найти как отучить крон отправлять почту о результатах своей работы.

Задача в /cron.d/backup выглядит примерно так:


0 2     * * *     root     nice -n 15 mysqldump .... | gzip > "/tmp/lb_billing.`date +\%F`.sql.gz" ;  cd /tmp ; wput "lb_billing.`date +\%F`.sql.gz".... ; rm *.gz >/dev/null 2>&1

В /etc/crontab опцию MAILTO="" добавлял.

Все без толку.

ОС - Debian 9

Наверно никак. У него отправка зашита в пузе, насколько я помню. Можно в исходниках посмотреть.

 

PS Или в современном мире юниксов уже неприлично туда заглядывать? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

1 час назад, vop сказал:

У него отправка зашита в пузе, насколько я помню. Можно в исходниках посмотреть.

чё, реально?! или это шутка юмора такая?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

1 час назад, Andrei сказал:

В /etc/crontab опцию MAILTO="" добавлял.

Все без толку.

Он переменную берет, в  /etc/crontab только переопределяется переменная, если там пусто, наследуется с пользователя/системы. Отключить только перенаправлением stdout в /dev/null , ну или заносите команды в скрипт и в нём предварительно переопределяйте на другой ящик.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.