Как я могу решить, почему мой PHP-скрипт не будет работать в cron, если он работает из командной строки? - PullRequest
1 голос
/ 21 июля 2010

У меня есть скрипт, который вызывает две функции, A и B, из одного класса.A создает виртуальный сервер Amazon, а B - один, используя shell_exec () из инструментов командной строки Amazon.Сценарий doActions.php извлекает действия из очереди.Если действие «создать», оно создает экземпляр;когда действие «уничтожить», оно убивает одного.

Скрипт отлично работает для выполнения A и B, когда я запускаю его из командной строки: php script.php.

Когда я ставлюэто на cron, он работает, но только успешно выполняет функцию B.Он удаляет уничтоженные экземпляры, но не создает их.

Точка сбоя, очевидно, является функцией B. Он задыхается в первом и наиболее важном shell_exec, ничего не возвращая и не повторяя.

echo $string = shell_exec('/home/user/public_html/domain.com/private/ec2-api-tools/bin/ec2-run-instances ami-23b6534a -k gsg-keypair -z us-east-1a');

Если вы не знаете что-то конкретное о том, как работают инструменты командной строки Amazon, предложите мне причины, по которым shell_exec может работать в одном случае, а не в другом.

Другой shell_exec в том же месте ведет себя как ожидалось:

echo $string = shell_exec ('echo overflow');

Я предполагаю, что он должен что-то делать с разрешениями.Но когда я запускаю shell_exec('whoami'), он возвращает «root», а когда я su и запускаю команду, он работает нормально.Мне трудно придумать творческие способы выяснить, почему мой скрипт PHP не будет работать в cron, если он работает из командной строки.Можете ли вы предложить некоторые?

1 Ответ

3 голосов
/ 21 июля 2010

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

ДляДля начала вы должны изменить скрипт, чтобы выводить текущую среду (shell_exec('env')?) в самом верху и проверять вывод из командной строки и cron.

Надеюсь, что-то будет очевидным, например AMAZON_EC2_VITAL_VAR но если нет, вам следует переместить среду cron к командной строке по одной, по одной переменной за раз, пока она не начнет работать.

Быстрый тест, чтобы убедиться в этом.Из командной строки выполните:

env >/tmp/pax_env.sh

Затем запустите сценарий PHP из сценария оболочки, который сначала выполняет:

. /tmp/pax_env.sh

, чтобы среды были идентичны.

И имейте в виду, что сама по себе su не дает вам ту же среду, которую вы получили бы при входе в систему непосредственно от конкретного пользователя (su -, я думаю ).Возможно, вы захотите проверить поведение при входе в систему как root напрямую.


Ваш комментарий:

Да, я верю, что вы его получили.Скорее всего, я отмечу ваш ответ как правильный, но вам нужно несколько слов о вашем умном решении.Прежде всего, как лучше всего выполнить скрипт pax_env.sh?Работает ли shell_exec ()?

Никогда не говорите, что я не работал за свои деньги :-) Нет. shell_exec почти наверняка будет запускать вспомогательную оболочку, поэтому переменные будутустановите в этой вложенной оболочки, но это не повлияет на родительский процесс PHP.

Мой совет, если вы хотите, чтобы все эти переменные были установлены, было бы создать сценарий оболочки, состоящий из всехкоманды в /tmp/pax_env.sh (возможно, с префиксом export), сопровождаемые командой, которую вы в настоящее время выполняете в cron, что-то вроде:

export PATH=.:/usr/bin
export PS1=Urk:
export PS2=MoreUrk:
/home/user/pax/scriptB.php

Затем выполните , что *Сценарий 1043 * из cron, а не /home/user/pax/scriptB.php напрямую.Это обеспечит настройку среды до вызова вашего PHP-кода.

Проницательные читатели заметят фразу «если вы хотите, чтобы все эти переменные были установлены» выше.Лично я не думаю, что это хорошая идея - поместить все переменные командной строки в сценарий оболочки для задания cron.Я бы предпочел на самом деле узнать, какие из них необходимы, и включить только те.Это уменьшает загрязнение, от которого должна работать ваша работа.Например, маловероятно, что для вашего сценария PHP потребуются переменные приглашения PS1/PS2.

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

Чтобы узнать, что нужно, нужно закомментировать по одному export за один раз, пока ваш сценарий снова не сломается.Тогда вы знаете, что переменная нужна.Как только он работает с максимальным количеством export закомментированных операторов, вы можете просто удалить эти закомментированные операторы экспорта в целом, и то, что остается, хотя и невероятно, должно быть в порядке (с извинениями сэра Артура Конан Дойля).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...