9

Я хочу использовать .sh скрипт для развертывания моего приложения. Этот скрипт находится на моем домашнем сервере (Ubuntu 15.10 Server) и помечен как исполняемый. Доступ к этому сценарию осуществляется через ssh, с помощью этого руководства я настроил ssh login, который запускает этот сценарий. Поэтому я просто вызываю ssh deployer@XXX.com someArguments и он запускает мой скрипт с некоторыми someArguments качестве параметров. У deployer пользователя uid = 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).

6 ответов6

5

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

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

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

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 формат

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 и full path имеют свои преимущества и недостатки, но в этом случае путь безопаснее:

#!/usr/bin/php
2

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

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

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

Источники:

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

1

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

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

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

which php
1

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

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

Я посмотрел учебник, которым вы следовали. Вы, вероятно, должны убедиться, что при обновлении command= to 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" в файле authorized_keys. Смотрите man-страницу, на которую я ссылался выше, для получения более подробной информации.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .