alibek Posted April 17, 2015 Posted April 17, 2015 Есть у меня несколько сервисных скриптов. Например такой: #!/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 просто удалить, то работа скрипта возобновляется. На какое-то время, а затем снова проблема повторяется. Никто с таким не сталкивался? Вставить ник Quote
BETEPAH Posted April 17, 2015 Posted April 17, 2015 (edited) может logrotate настроен на ваш output.log? это веду к тому, что может что-то с правами Edited April 17, 2015 by BETEPAH Вставить ник Quote
vop Posted April 17, 2015 Posted April 17, 2015 (edited) Бывают обрывки вывода при падении в корку. Как вариант, скрипт натыкается на письмо с какими-нибдуь "неправильными" символами внутри, и подрывается на них. Проверьте обработку текста. Edited April 17, 2015 by vop Вставить ник Quote
alibek Posted April 17, 2015 Author Posted April 17, 2015 Как вариант, скрипт натыкается на письмо с какими-нибдуь "неправильными" символами внутри, и подрывается на них. Возможно, в электронной почте куча подобных ситуаций. Но почему тогда не срабатывают следующие вызовы планировщика (через час)? это веду к тому, что может что-то с правами Права 644, владелец user1. Для пробы я делал права 666, не помогало. Вставить ник Quote
vop Posted April 17, 2015 Posted April 17, 2015 Возможно, в электронной почте куча подобных ситуаций. Там ожет быть еще путаница с кодесетами... Но то уже такое. Но почему тогда не срабатывают следующие вызовы планировщика (через час)? Он насовсем перестает работать? Но вот это же должно хотя бы выводиться: echo "Call job1, `date`..." Если выводится, и при каждом запуске затыкается на выводе строки "fro", может, как раз, и первым в обработке и стоит "кривое" письмишко? Надо бы его глянуть, может что там ломано. И еще вопросик - при обработке сообщений там все правильно устанавливается (блокировки и т.д.)? Может там с конкурентным доступом что-нибудь не так? Вставить ник Quote
alibek Posted April 17, 2015 Author Posted April 17, 2015 Он насовсем перестает работать? Но вот это же должно хотя бы выводиться: Вот именно. Как будто крон выключился. Или как будто не хватает прав на добавление текста в output.log. Но крон работает (другие задания выполняются) и права на файле 644 с владельцем user1. Если выводится, и при каждом запуске затыкается на выводе строки "fro", может, как раз, и первым в обработке и стоит "кривое" письмишко? Если скрипт запустить вручную, он это письмо обрабатывает нормально. И еще вопросик - при обработке сообщений там все правильно устанавливается (блокировки и т.д.)? «Там» это где? На сервере электронной почты? Вставить ник Quote
adron2 Posted April 17, 2015 Posted April 17, 2015 Может скрипт слишком долго работает и крон его по таймауту прибивает? А из за такого прибивания буфер stdout нормально не сбрасывается в файл? Попробуйте запускать скрипт через setsid и на конце & Вставить ник Quote
alibek Posted April 17, 2015 Author Posted April 17, 2015 Может скрипт слишком долго работает и крон его по таймауту прибивает? Может и так. У IMAP таймауты большие. Правда это по идее не должно мешать повторному вызову. Попробуйте запускать скрипт через setsid и на конце & Через setsid запускать скрипт-обертку или PHP-скрипт? Вставить ник Quote
alibek Posted May 13, 2015 Author Posted May 13, 2015 Любопытная статистика накопилась. Скорее всего дело вообще не в правах доступа. Итак, в планировщик добавлена примерно такая строчка: 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 создается какой-то неправильный и в него невозможно дописать данные. Вставить ник Quote
vop Posted May 13, 2015 Posted May 13, 2015 Если обрывается на полуслове, или вообще ничего не выводит, то, возможно, вылетает по сегментейшн фаулт. Сам крон по емейлу что пишет? Вставить ник Quote
altnetwork.ru Posted May 13, 2015 Posted May 13, 2015 (edited) У меня когда-то была примерно такая же проблема: при интерактивном запуске отрабатывало, при запуске из крона - результат был непредсказуемый. "Вылечилось" примерно такой крон-строкой: 02 05 * * * . /homeuser/.profile;/usr/bin/script Edited May 13, 2015 by altnetwork.ru Вставить ник Quote
alibek Posted May 13, 2015 Author Posted May 13, 2015 Сам крон по емейлу что пишет? Ничего. core-файлов тоже нигде не видно. К тому же я ведь не рестартую crond. Я планировщик вообще не трогаю, но если я создаю файл output.log с содержимым, то задания начинают отрабатывать нормально. "Вылечилось" примерно такой крон-строкой А что это дает? Мой user1 - это служебный пользователь, у которого нет home. Просмотрел свой home - там только переменные окружения выставляются. А в рутовом - и того нет. Вставить ник Quote
ttttt Posted May 13, 2015 Posted May 13, 2015 Уверен, что с буферизацией самого php разобрался? ob_flush() и flush() в конце программы попробуй Вставить ник Quote
alibek Posted May 13, 2015 Author Posted May 13, 2015 Я где-то читал, что когда PHP запускается интерактивно (php_sapi_name()=='cli'), то он сам отключает буферизацию. Но даже если это не так, я почти на 100% уверен, что причина не в буферизации. Во-первых, такое же поведение наблюдается и для perl-скриптов, в которых я отключаю буферизацию ($|=1). Во-вторых, это не объясняет, почему в файле output.log нет вывода команды date, которая указана в sh-файле перед запуском собственно скрипта. Вставить ник Quote
nu11 Posted May 14, 2015 Posted May 14, 2015 Я бы для начала посмотрел логи php. И уберите обертку, она не нужна. Вывод в файл также не самый удачный подход для логирования. Вставить ник Quote
alibek Posted May 14, 2015 Author Posted May 14, 2015 Я бы для начала посмотрел логи php. А такое бывает? Где их можно посмотреть? Вставить ник Quote
GrandPr1de Posted May 14, 2015 Posted May 14, 2015 Я бы для начала посмотрел логи php. А такое бывает? Где их можно посмотреть? сомнительно что бывает, а вот обертку можно и убрать и вызывать из под пхп date() Вставить ник Quote
DDR Posted May 14, 2015 Posted May 14, 2015 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 Вставить ник Quote
nu11 Posted May 17, 2015 Posted May 17, 2015 А такое бывает? Где их можно посмотреть? Включите их в php.ini error_log = /path/filename Вставить ник Quote
MagMike Posted May 17, 2015 Posted May 17, 2015 есть подозрение, что крон запускает новое задание (скажем, в 10 минут), когда не закончилось выполнение предыдущего (запущенного, скажем, в 05 минут) php-скрипт реентерабелен? Вставить ник Quote
alibek Posted May 17, 2015 Author Posted May 17, 2015 Планировщик запускается раз в час, скрипт выполняется в среднем менее минуты (иногда бывает дольше из-за больших таймаутов IMAP). Параллельный запуск двух экземпляров по идее мешать не должен, там нет причин для взаимных блокировок. Обертку переделаю, посмотрю как это повлияет. Но сейчас уже третьи сутки задания выполняются нормально. Я пока ничего не менял. Вставить ник Quote
Andrei Posted November 8, 2019 Posted November 8, 2019 Банально, но что-то не могу найти как отучить крон отправлять почту о результатах своей работы. Задача в /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 Вставить ник Quote
vop Posted November 8, 2019 Posted November 8, 2019 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 Или в современном мире юниксов уже неприлично туда заглядывать? :) Вставить ник Quote
Andrei Posted November 8, 2019 Posted November 8, 2019 1 час назад, vop сказал: У него отправка зашита в пузе, насколько я помню. Можно в исходниках посмотреть. чё, реально?! или это шутка юмора такая? Вставить ник Quote
jffulcrum Posted November 8, 2019 Posted November 8, 2019 1 час назад, Andrei сказал: В /etc/crontab опцию MAILTO="" добавлял. Все без толку. Он переменную берет, в /etc/crontab только переопределяется переменная, если там пусто, наследуется с пользователя/системы. Отключить только перенаправлением stdout в /dev/null , ну или заносите команды в скрипт и в нём предварительно переопределяйте на другой ящик. Вставить ник Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.