Как написать оболочку, избегая подоболочки, для перезаписи карт apache2 или сценариев оболочки в целом?

Я запускаю карту перезаписи с помощью внешней программы перезаписи (prg) в apache2, которая может вызвать ошибку и умереть. Когда карта перезаписи больше не работает, система, очевидно, не работает должным образом.

Поэтому я хотел запустить простой сценарий оболочки-оболочки, который сам выполняет программу карты (написанную на php) и перезапускает ее, если она умирает:

#!/bin/bash
until /usr/bin/php /somepath/mymap.php; do
  echo "map died but i will restart it right away!" 
done

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

... а затем связывается с механизмом перезаписи через его дескрипторы файлов stdin и stdout. Для каждого поиска функции карты он получит ключ для поиска в виде строки с символом новой строки в конце на стандартном вводе. Затем он должен вернуть искомое значение в виде строки, заканчивающейся новой строкой, на стандартный вывод или четырехсимвольной строки ``NULL'', если это не удается...

Причина мне кажется вполне понятной. Первый скрипт принимает стандартный ввод, но не перенаправляет его на сабскрипт.

Я думаю, мне как-то нужно определить дескриптор, используя exec, и правильно перенаправить stdin/stdout скриптов. Но как мне это сделать?


person The Surrican    schedule 03.01.2012    source источник
comment
В новом файле mymap.php автоматически будут правильно назначены стандартный ввод и стандартный вывод. Причина кажется мне довольно ясной - ну, не мне.   -  person kubanczyk    schedule 03.01.2012
comment
вот почему я публикую этот вопрос здесь;) я думаю, что часто бывает, что люди не могут решить проблему, потому что тривиальные мысли застревают в каком-то неверном направлении.   -  person The Surrican    schedule 04.01.2012


Ответы (3)


Распространенной проблемой является то, что некоторые скрипты выполняются "вручную" и не работают при косвенном выполнении (через cron или из apache).

Обычно основной причиной является одна из:

  1. вашему скрипту нужна дополнительная переменная среды (PATH, LD_LIBRARY_PATH и т. д.)
  2. ваш скрипт требует терминал

Первое, что нужно сделать, это получить некоторую отладочную информацию, поэтому добавьте в свой скрипт:

env > /tmp/$0.env # get environment

и получить стандартный вывод:

... /usr/bin/php /somepath/mymap.php 2>/tmp/$0.stderr ...

Это может привести вас к решению.

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

Удачи.

person Michał Šrajer    schedule 03.01.2012

Михал Шрайер указал одну очень распространенную причину проблем (окружающая среда). Вы, безусловно, должны быть уверены, что среда настроена достаточно хорошо, потому что Apache строго устанавливает свою собственную среду и не передает какие-либо унаследованные ненужные значения; он передает только то, для чего настроен (директивы SetEnv и PassEnv, IIRC).

Другая проблема заключается в том, что вы думаете, что ваш процесс отображения не удастся; это беспокоит. Далее, это симптом еще одной проблемы, которую я считаю основной.

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

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

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

Может быть:

if tee /tmp/xx.$$ | /usr/bin/php /somepath/mymap.php
then : OK
else
     until /usr/bin/php /somepath/mymap.php < /tmp/xx.$$
     do echo "map died but I will restart it right away!"
     done
fi
rm -f /tmp/xx.$$

Нерешенные проблемы включают в себя:

  • Вы должны добавить ловушки, чтобы убедиться, что временный файл удален;
  • Вероятно, вам не следует использовать /tmp в качестве каталога;
  • Сообщения, вероятно, не отправляются на веб-сервер, а оттуда в клиентский браузер, пока общий скрипт не завершится, поэтому эхо-сообщения просто испортят начало ответа;
  • Количество отказов не ограничено;
  • Отсутствует протоколирование сбоев;
  • Нет попытки исправить проблему, вызвавшую сбой;
  • И есть, вероятно, другие, о которых я еще не подумал.
person Jonathan Leffler    schedule 03.01.2012
comment
отличная идея буферизовать ввод для неудачной попытки и думать об этом тупике. запросы не критичны, а те, которые могут привести к падению карты, скорее всего, все равно недействительны. мне не нужно следить за тем, чтобы каждый запрос обрабатывался должным образом, мне просто нужно убедиться, что карта не останавливается. поскольку кажется, что проблема заключается не в том направлении, в котором я думал, я думаю, что сделаю что-то в направлении, которое вы предложили, и спасибо за отличные замечания. - person The Surrican; 04.01.2012

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

независимо от того, это то, что вы хотите сделать:

while true; do
    /usr/bin/php /somepath/mymap.php
done

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

person Samus_    schedule 03.01.2012
comment
звучит разумно! спасибо, постараюсь отлаживать в этом направлении! - person The Surrican; 04.01.2012