Как написать оболочку - избегая подоболочек - сценарий для карт переписывания apache2 или сценарии оболочки в целом? - PullRequest
3 голосов
/ 03 января 2012

Я запускаю карту перезаписи с помощью внешней программы перезаписи (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 сценариев. Но как мне это сделать?

Ответы [ 3 ]

3 голосов
/ 03 января 2012

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

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

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

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

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

и получите stderr:

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

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

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

Удачи.

2 голосов
/ 04 января 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 в качестве каталога;
  • Сообщения, вероятно, не отправляются на веб-сервер и оттуда в браузер клиента до тех пор, пока не завершится весь сценарий, поэтому отраженные сообщения просто портят начало ответа;
  • Количество сбоев не ограничено;
  • Нет регистрации ошибок;
  • Не предпринимается попытка исправить проблему, вызвавшую сбой;
  • И, наверное, есть другие, о которых я еще не думал.
1 голос
/ 04 января 2012

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

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

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

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

...