У меня есть сценарий, который вызывает две функции, A и B, из одного класса. A создает виртуальный сервер Amazon, а B уничтожает его, как с помощью shell_exec () из инструментов командной строки Amazon. Сценарий doActions.php выталкивает действия из очереди. Если действие «создает», оно создает экземпляр; когда действие «уничтожает», оно убивает одного.
Скрипт отлично работает для выполнения как A, так и B, когда я выполняю его из командной строки: php script.php.
Когда я помещаю его в cron, он запускается, но только успешно запускает функцию B. Он удаляет экземпляры destroys, но не создает их.
Точка отказа – это явно функция 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, когда это произойдет из командной строки. Можете ли вы предложить некоторые?
Когда что-то выполняется из командной строки, но отказывается делать это в cron
, это часто является проблемой среды (путь или какая-либо другая переменная среды, которая требуется для кода, который вы используете).
Для начала вы должны изменить сценарий для вывода текущей среды ( shell_exec('env')
?) На самом верху и проверить вывод из командной строки и cron.
Надеемся, что будет что-то очевидное, такое как AMAZON_EC2_VITAL_VAR
но если нет, вы должны переместить среду cron в свою командную строку по одной переменной за раз, пока она не начнет работать.
Быстрый тест, чтобы убедиться в этом. Из командной строки выполните:
env >/tmp/pax_env.sh
Затем запустите свой PHP-скрипт из сценария оболочки, который сначала выполняется:
. /tmp/pax_env.sh
так что среды одинаковы.
И имейте в виду, что сам по себе не дает вам такой же среды, какой вы могли бы получить при входе в систему напрямую как определенный пользователь (кажется, я думаю ). Вы можете проверить поведение, когда вы входите в систему с правами root.
Ваш комментарий:
Да, я верю, что у тебя это есть. Я, вероятно, буду отмечать ваш ответ как правильный, но вам нужно страдать через несколько дополнений в отношении вашего умного решения. Во-первых, каков наилучший способ выполнить сценарий pax_env.sh? Работает ли shell_exec ()?
Никогда не позволяйте этому говорить, что я не работал на свои деньги 🙂 Нет. shell_exec
почти наверняка будет работать под-оболочкой, поэтому переменные будут установлены в этой под-оболочке, но не повлияют на родительский процесс PHP.
Мой совет, если бы вы хотели, чтобы все эти переменные были установлены, заключалось бы в создании shell-скрипта, состоящего из всех команд в /tmp/pax_env.sh
(вероятно, с префиксом каждого с export
), за которым следует команда, которую вы в настоящее время выполняете в cron
, что-то в соответствии с:
export PATH=.:/usr/bin export PS1=Urk: export PS2=MoreUrk: /home/user/pax/scriptB.php
Затем запустите этот скрипт из cron
а не /home/user/pax/scriptB.php
. Это обеспечит настройку среды до того, как будет вызван код PHP.
Удивительные читатели заметили фразу «если бы вы хотели, чтобы все эти переменные были установлены» выше. Я лично не считаю, что неплохо было бы сбросить все переменные командной строки в сценарий оболочки для задания cron
. Я бы предпочел узнать, какие из них нужны, и только включать их. Это уменьшает загрязнение, которое должно выполнять ваша работа cron. Например, маловероятно, чтобы переменные запроса PS1/PS2
были необходимы для вашего PHP-скрипта.
Если он работает, вы можете установить все переменные среды – я просто предпочитаю абсолютный минимум, поэтому мне не нужно слишком беспокоиться, когда что-то меняется.
Способ узнать, что нужно, – прокомментировать один export
за раз, пока ваш скрипт не сломается снова. Тогда вы знаете, что переменная нужна. После того, как он будет работать с максимальным количеством заявлений export
, вы можете просто удалить те комментарии, которые были высказаны в отношении экспорта, и то, что осталось, каким бы невероятным оно ни было, должно быть в порядке (с извинениями сэра Артура Конан Дойла).