Я нахожусь в процессе настройки сервера Ubuntu 14.04 для автоматизации сборки гибридных приложений Android с помощью CLI Phonegap. Написав все соответствующие сценарии, я столкнулся с довольно странной проблемой: когда я подключаюсь к своему серверу по SSH, я могу запустить сценарий и успешно выполнить все команды Phonegap в сеансе интерактивной оболочки. Однако каждая попытка запустить те же самые команды в автоматизированном сценарии, который запускается каким-либо другим событием, сгенерированным посетителем, терпит неудачу. Чтобы определить проблему, я свел ее к простому эксперименту, который я описываю ниже.
Шаг 1. Напишите сценарий запуска, pgtest
в /etc/init.d
#! /bin/bash
source ~/.nvm/nvm.sh;
nvm use stable;
cd /home;
ls >> /tmp/ls;
which node >> /tmp/node;
which git >> /tmp/git;
which phonegap >> /tmp/pgp;
phonegap -v >> /tmp/pgpv 2>/tmp/pgpe;
Пояснения
- Я запускаю NVM, чтобы использовать стабильную (4.1.1.) версию Node + NPM.
- Я хочу убедиться, что мой пакетный файл действительно выполняется, поэтому я делаю
ls /home
и передаю его вывод в файл/tmp/ls
. - Я хочу быть уверен, что node, git и phonegap действительно доступны, поэтому я передаю вывод из
which node|git|phonegap
в файлы в папке/tmp
. - Нет смысла все усложнять, поэтому я выдаю самую простую из команд Phonegap,
phonegap -v
, чтобы сообщить номер текущей версии. Любые ошибки, которые могут возникнуть при этом, передаются в файл/tmp/pgpe
. ls
- список папок для папки/home
присутствует и верен.
Шаг 2. Убедитесь, что pgtest
выполняется последним ln -s /etc/init.d/pgtest /etc/rc2.d/S04PGTest
Объяснение. Я хочу, чтобы этот скрипт запускался только после того, как все остальное на моем сервере запустится
Со всем этим я перезагрузился на сервере и проверил содержимое папки /tmp
. Мои выводы
node
,git
иpgp
указывают на расположение Node, Git и Phonegap.pgpv
, который должен содержать номер версии Phonegap, ПУСТОЙ.pgpe
присутствует и НЕ пусто/tmp/ls
присутствует и заполняется списком папок/home
, как и раньше
Последнее означает, что система обнаружила ошибку при попытке выполнить phonegap -v
. Вот содержимое файла pgpe
.
путь.js: 8
throw new TypeError('Путь должен быть строкой. Получено ' +
^
TypeError: Путь должен быть строкой. Получено неопределенное
в assertPath (path.js:8:11)
в Object.posix.join (path.js:477:5)
на Объект.
(/root/.nvm/versions/node/v4.1.1/lib/node_modules/phonegap/node_modules/phonegap-build/lib/common/config/global.js:17:28)
в Module._compile (module.js:434:26)
в Object.Module._extensions..js (module.js:452:10)
в Module.load (module.js:355:32)
в Function.Module._load (module.js:310:12)
в Module.require (module.js:365:17)
при необходимости (module.js:384:17)
на Объект. (/root/.nvm/versions/node/v4.1.1/lib/node_modules/phonegap/node_modules/phonegap-build/lib/common/config.js:9:13)
Теперь вот что любопытно. Если я удалю папку /tmp
и выполню /etc/init.d/pgtest
в сеансе интерактивной оболочки, я получу следующие результаты.
/tmp/node
,/tmp/git
/tmp/pgp
присутствуют и верны/tmp/pgpv
reports5.3.6
- номер текущей версии Phonegap/tmp/pgpe
EMPTY , т. е. об ошибках не сообщается.- Просто убедитесь, что переменная PATH внутри вашего скрипта такая же, более длинная, которую вы видите в diff, а затем повторите попытку автоматически.
Очевидно, что в интерактивной среде оболочки bash есть что-то, чего нет, когда я запускаю автоматический сценарий — в данном случае при запуске, но это также происходит, когда я запускаю процесс через автоматический сценарий любым другим способом.
Со всем этим я приближаюсь к установлению причины проблемы. Однако мои знания о том, как работают эти системы, меня подводят. В чем разница между интерактивной оболочкой и той, с которой сталкивается мой автоматизированный сценарий? Как мне интерпретировать ошибки, о которых сообщается в /tmp/pgpe
? Что мне делать, чтобы исправить их?
Я был бы очень благодарен любому, кто мог бы поставить меня на правильный путь здесь.
Отредактируйте в свете предложений @Eduardo. Я взял два набора окружений (интерактивное и init.d). Результаты выполнения DIFF (интерактивного и init.d) можно найти в этой скрипте. Несколько менее доступный дамп результата DIFF показан ниже.
Я почти уверен, что пробовал это в своих собственных экспериментах до публикации этого вопроса, но, следуя предложению @Eduardo ниже, я попытался вставить
Я использую NVM для управления узлом, поэтому я уверен, что система знает, где найти nvm.sh.
вверху скрипта - чуть ниже строки source ~/.nvm...
. После перезагрузки результат был тот же: пустой /tmp/pgpv
и те же ошибки в /tmp/pgpe
.
EXPORT PATH=/opt/android/platform-tools:/opt/android/tools:/opt/android:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Единственное, что я здесь изменил — замаскировал имя хоста и IP-адрес клиента SSH.
~
при запуске из сценария перезагрузкиinit.d
. Я изменил строку _3_ на _4_ и перезагрузился. На этот раз файл _5_ был пуст — когда я выполняю _6_ из интерактивной оболочки, я получаю листинг, содержащий _7_. _8_ до сих пор сообщает _9_. Я не устанавливаю настройки PG, узла и т. д. самостоятельно. Я просто запускаю NVM, и он запускает Nod и т. д. Это дает ценную подсказку, но я не понимаю, как ее интерпретировать или решить проблему. - person Etan Reisner   schedule 09.11.2015~
init.d
почти наверняка не расширится до чего-нибудь полезного. Не используйте его. Используйте явный путь. Также пожалуйста используйте форматирование кода (инструментcd /home
) для блоков ввода, чувствительных к пробелам, а не инструмент цитирования. - person DroidOS   schedule 11.11.2015init.d
без каких-либо изменений в результатах. Я только что попробовал ваше второе предложение. Он только что сообщил~
. - person Etan Reisner   schedule 11.11.2015