/ usr / bin / env: php: Нет такого файла или каталога

9

Я хочу использовать .sh скрипт для развертывания моего приложения. Этот скрипт находится на моем домашнем сервере (Ubuntu 15.10 Server), помечен как исполняемый. Доступ к этому сценарию осуществляется через ssh, с помощью этого руководства я настроил ssh login, который запускает этот сценарий. В общем, я просто звоню, ssh deployer@XXX.com someArgumentsи он запускает мой сценарий с someArgumentsпараметрами. У пользователя deployeruid = 0, поэтому его в основном root(это будет изменено в будущем, я установил его только для устранения проблем с разрешениями, пока он не будет работать нормально).

И вот тут все становится сложнее. Скрипт сообщает /usr/bin/env: php: No such file or directoryпо команде /bin/composer install(используя Composer ). Чем страннее я смотрю на этот сценарий, тем страннее. Перед этой строкой также вызывается /bin/composer self-updateи /bin/composer -V, который работает правильно и отображает правильный вывод.

Я проверил следующие вещи:

  • /usr/bin/env php -vотображает правильную версию PHP (так же, как /usr/bin/php -v)
  • whereis php дисплеи php: /usr/bin/php /usr/local/bin/php /usr/share/man/man1/php.1.gz
  • php5-cli пакет установлен и самая новая версия
  • $PATH содержит /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
  • which env дисплеи /usr/bin/env

Я также попробовал следующие вещи:

  • запуск скрипта напрямую как bash deploy.shпод root (так как он такой же, как у этого пользователя) - отлично работает без ошибок
  • запуск сбойных команд напрямую - также без ошибок

Так что это кажется мне очень специфическим случаем, почему эта команда не работает. Я потратил 12 часов на его отладку, и у меня нет идей здесь.

PS: Подобная ошибка ( /usr/bin/env: node: No such file or directory) возникает, когда есть bower install(с помощью Bower ), но не при работе npm install(с использованием NPM ).

Томаш Блатны
источник
Беги sh deployвместо bash deploy(возможно, какой-то башизм). Как вы проверили « следующие вещи »? Я рекомендую проверить их в сценарии, чтобы вы могли обнаружить возможные переопределения и санации envs.
Джакомо Катенацци
по поводу « следующих вещей »: я добавил их в начало сценария deploy.sh, и они выводят эти вещи, которые я поставил под сомнение. Тот же вывод, когда я запускаю их в одиночку.
Томаш Блатны
sh deployи bash deployоба дают одинаковые результаты
Томаш Блатны
Покажите эту строку здесь, пожалуйста. Я рекомендую вам заменить команду php в этой строке в вашем скрипте выводом в файл, чтобы проверить переменные среды в момент вызова / usr / bin / env:/usr/bin/env > environment.txt
Олег Болден

Ответы:

6

Убедитесь, что окончания строк и / или невидимые пробелы не вызывают проблемы.

Удалите пробелы в первой строке скрипта и вставьте новые, следя за тем, чтобы не удерживать CTRL при нажатии пробела.

Кроме того, убедитесь, что у вас нет окончания строки DOS (CR + LF). См. Https://stackoverflow.com/questions/82726/convert-dos-line-endings-to-linux-line-endings-in-vim для получения подробной информации.

Neuhaus
источник
Я использую IDE, которая автоматически проверяет (и конвертирует) только CR + LF в LF, удаляет спецификацию и заботится о белых символах, но я дважды проверила ее, и она выглядит нормально (хотя все еще не работает). В любом случае, спасибо
Томаш Блатны
4

Самый простой способ .... изменить пользовательскую оболочку как скрипт.

/ И т.д. / пароль

Before:
deploy:x:0:0:,,,:/root:/bin/bash

After:
deploy:x:0:0:,,,:/root:/scripts/deploy.sh

Пример сценария (убедитесь, что бит выполнения установлен в chmod + x)

/scripts/deploy.sh

#!/bin/bash 
PATH=$PATH:/moo etc...
moo.sh

Образец Работает каждый раз! Вы даже должны иметь возможность использовать сценарий для устранения неполадок / отладки любых переменных env, которые, по вашему мнению, не установлены и т. Д. ... также будут работать аргументы обработки, передаваемые в ssh.

Примечание. Рекомендуется всегда ПОЛНОСТЬЮ КВАЛИФИЦИРОВАТЬ пути для любых сценариев, исполняемых файлов и т. Д. Выше приведен лишь пример, который позволяет задавать путь по умолчанию для вызова moo.sh в папке moo;)

Это было легко .. Спасибо за публикацию ..

Ссылка: / etc / passwd формат

NotAdmin Dave
источник
Хороший ответ, но я на самом деле никогда не использую пользователя на сервере напрямую, я всегда sshна сервере, и, по очереди authorized_keys, вызывается скрипт, а затем соединение заканчивается. Как мне изменить, authorized_keysчтобы это работало?
Томаш Блатны
Это должно работать так же. Вы будете проходить аутентификацию по ключу, и пока оболочка настроена на сценарий для рассматриваемой удаленной учетной записи в файле / etc / passwd удаленного сервера, который будет выполнять сценарий. Я добавлю скриншот к своему сообщению в ближайшее время.
NotAdmin Dave
1
@ Дэйв не может дождаться твоей книги
Бурги
Спасибо за ваш ответ, он не решил мою проблему, но был для меня самым интересным и фактически решил другие проблемы, которые у меня были. Дарил вам награду, еще раз спасибо
Томаш Блатны
4

Команда envпросматривает пользователя, $PATHчтобы найти первый исполняемый файл с заданным именем. Таким образом, /usr/bin/env phpбудет искать исполняемый файл, который вызывается phpв любом из каталогов $PATHпользователя, который его запускает.

В вашем случае это почти наверняка, потому что при запуске команды поверх sshвы не запускаете полную оболочку и фактически не читаете файлы инициализации вашей оболочки. Вы можете проверить это, выполнив эту команду (обратите внимание на одинарные кавычки):

ssh deployer@XXX.com 'echo $PATH'

И сравнивая вывод с тем, что вы получаете, если вы ssh deployer@XXX.comи затем запускаете echo $PATH. В моей системе. например:

$ echo $PATH
/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:

$ ssh localhost 'echo $PATH'
/usr/bin:/bin:/usr/sbin:/sbin

Следовательно, $PATHдоступ к вашему сценарию при запуске ssh deployer@XXX.comне совпадает с тем, когда вы входите в систему для его тестирования.

В любом случае, простое решение - использовать полный путь к интерпретатору вместо env. Оба envпути и полные пути имеют свои преимущества и недостатки, но в этом случае путь безопаснее:

#!/usr/bin/php
terdon
источник
ITYM " обратите внимание на одинарные кавычки" не " не ".
dave_thompson_085
@ dave_thompson_085 действительно, спасибо.
тердон
Я на самом деле использую полные пути везде, как я уже упоминал в своем вопросе, ошибка сообщается внутри composer install команды, которую я, очевидно, не могу изменить. Также $PATHвсе в порядке, как я уже упоминал в своем вопросе, я проверил все вещи, добавив их в скрипт и запустив удаленно через ssh login. Также я не могу проверить, ssh deployer@XXX.com 'echo $PATH'как вы заявили, так как мой логин ssh ограничен только одним сценарием, но я проверял его, когда добавлял $ PATH к этому сценарию (указано выше). В любом случае, спасибо за ваш ответ и принимаю + 1 для объяснения мне envвещи
Томаш Блатны
@ TomášBlatný хорошо, вы где-то используете env, иначе вы не увидите эту ошибку. Я не знаю composer, но вам, вероятно, придется скопировать или связать исполняемый файл php с каталогом в его пути. Подобные вещи трудно отлаживать, поскольку существует так много вещей, каждая из которых зависит от другой.
тердон
Это правда, envна самом деле называется внутри композитора. Но это не решает проблему, почему некоторые вызовы композитора проходят, а некоторые нет. Однако я буду дальше исследовать это, изучая его код. Спасибо за ваше время
Томаш Блатны
2

Возможно ли, что bashтребуется сброс к своей хэш-таблице?

Если это так, вы можете попробовать добавить hash -rгде-нибудь в своем скрипте, что заставляет оболочку просматривать $PATHснова, а не полагаться на (возможно, устаревшую) информацию из хеш-таблицы.

При необходимости hashможно также включить оболочку для запоминания путей к исполняемым файлам, установленным в нестандартных местах, с помощью этой -pопции или забыть пути с помощью этой -dопции.

Источники:

https://unix.stackexchange.com/a/86017/121251
https://stackoverflow.com/a/22543353/2146843

flyingfinger
источник
Это не решило проблему для меня, но это хорошее знание, поэтому я добавил вам +1
Томаш Блатны
1

Похоже, может быть, вам нужно добавить php к вашему пути. Пытаться:

vim ~/.bashrc
PATH=$PATH:/usr/local/bin/php
export PATH

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

which php
Jeramy
источник
Ну, это не проблема, так как php -vвыводит правильную версию PHP и composer --versionвыводит версию композитора. Как я уже сказал, проблема только в одной команде.
Томаш Блатны
1

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

Первое, что нужно сделать, чтобы подтвердить, что у вас есть проблема с PATH, - обновить скрипт развертывания, чтобы записать выходные данные envили хотя бы echo $PATH. Я предполагаю, что, как называется ваш сценарий развертывания, $ PATH установлен не так, как вы ожидаете. Этот отладочный вывод подтвердит / опровергнет мою теорию.

Я посмотрел учебник, которым вы следовали. Вы, вероятно, должны убедиться в обновлении, command=чтобы быть, command="/bin/sh /path/to/your/script..."если вы еще не удостоверились, что ваш скрипт запускается правильной оболочкой.

Если у вас есть проблема с PATH, быстрое / грязное решение состоит в том, чтобы просто установить PATH в начале сценария развертывания.

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

Подробное объяснение и дальнейшие варианты ...

В Linux, когда команды выполняются, они наследуют среду своего родительского процесса.

Когда вы входите в систему как обычный пользователь через SSH, случаются некоторые вещи (например, запуск / etc / bashrc / etc / profile ~ / .bash_profile ~ / .bashrc и т. Д.). В этот момент вы, возможно, обновили среду своего процесса, выполнив действия, подобные export PATH="$PATH:~/mybin"тем, что описаны в этих сценариях. Теперь все будущие процессы, которые вы запускаете, унаследуют вашу текущую среду.

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

Страница man для авторизованных ключей описывает, что происходит после аутентификации. Относительно окружающей среды:

  1. Читает файл ~ / .ssh / environment, если он существует, и пользователям разрешено изменять свою среду. Смотрите параметр PermitUserEnvironment в sshd_config (5).

Таким образом, подходящее место для настройки среды для процесса находится в том месте, ~/.ssh/environmentгде ~находится домашний каталог пользователя, который прошел проверку подлинности для запуска команды. Вам также необходимо проверить ваш sshd_config, чтобы убедиться, что PermitUserEnvironment разрешен.

~/.ssh/environment формат также указан в справочной странице, конечно.

         This file is read into the environment at login (if it exists).
         It can only contain empty lines, comment lines (that start with
         '#'), and assignment lines of the form name=value.  The file
         should be writable only by the user; it need not be readable by
         directory becomes accessible.  This file should be writable only
         by the user, and need not be readable by anyone else.

Альтернативный способ указать среду без использования вышеупомянутого метода - использовать environment="NAME=value"опцию в файле авторизованных ключах. Смотрите man-страницу, на которую я ссылался выше,

mattpr
источник
Относительно Without knowing exactly how you have setup your deploy script to run: в моем вопросе в начале есть ссылка, как я ее настроил (используя ~/.ssh/authorized_keys. Спасибо за подсказку с командой обновления, я попробовал, но, к сожалению, без разницы. Однако я буду дальше исследовать это и пробовать различные оболочки Пожалуйста, примите +1 за эту идею.
Томаш Блатны
Вы пытались обновить скрипт развертывания, чтобы распечатать текущий $ PATH? Не могли бы вы опубликовать результат? Если он не соответствует ожидаемому, вы можете просто попытаться установить PATH явно, как я предлагал в начале вашего сценария развертывания.
Mattpr