/ usr / bin / env: php: Немає такого файлу або каталогу


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 (за допомогою Композитор ). Все більш дивно, чим більше я дивлюся на цей сценарій. Перед цим рядком також називається /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 годин на налагодження, і я не мав тут ідей.

P.S .: Подібна помилка ( /usr/bin/env: node: No such file or directory ) виникає, коли є bower install (за допомогою Бауер ), але ні під час запуску npm install (за допомогою НПМ ).


Запустити sh deploy замість bash deploy (може бути, якийсь башизм). Як ви перевірили " наступні речі "? Рекомендую перевірити їх у скрипті, щоб ви могли виявити можливі заміщення та санітації envs.
Giacomo Catenazzi

щодо " наступні речі ": Я додав їх до запуску сценарію deploy.sh, і вони виводять ці речі, які я ставлю під сумнів.
Tomáš Blatný

sh deploy і bash deploy обидва дають однакові результати
Tomáš Blatný

Покажіть цю лінію, будь ласка. Я рекомендую вам замінити php команда на цьому рядку сценарію з виходом у файл для перевірки змінних середовища на момент виклику / usr / bin / env: /usr/bin/env > environment.txt
Oleg Bolden

Відповіді:


5

Переконайтеся, що закінчення рядків та / або невидимі пробіли не викликають проблеми.

Видаліть пробіли в першому рядку скрипта і вставте нові, переконавшись, що не утримуйте клавішу CTRL, натиснувши пробіл.

Також переконайтеся, що у вас немає кінцевих рядків DOS (CR + LF). Подивитися https://stackoverflow.com/questions/82726/convert-dos-line-endings-to-linux-line-endings-in-vim для деталей.


Я використовую IDE, який автоматично перевіряє (і перетворює) CR + LF тільки в LF, видаляє специфікацію і піклується про білих символів, але я двічі перевірив його, і це виглядає нормально (все ще не працює). Все одно, дякую
Tomáš Blatný

4

Найпростіший спосіб .... змінити оболонку користувача як сценарій.

/ etc / passwd

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

Sample Працює кожного разу! Ви навіть повинні мати можливість використовувати скрипт для усунення / усунення несправностей будь-яких змінних env, які, на вашу думку, можуть бути видалені і т.д., а також аргументи обробки, які передаються в ssh, також будуть працювати.

Примітка: його найкраща практика завжди ПОЛЬОВО КВАЛІФІВАТИ шляхи для будь-яких скриптів, виконуваних файлів і т.д.

Це було легко .. Дякуємо за публікацію ..

Довідка: / etc / passwd формат


Приємна відповідь, але я фактично ніколи не використовую користувача на сервері прямо, я завжди ssh до сервера, і за допомогою смуги в authorized_keys, скрипт викликається, а потім з'єднання завершується. Як змінити authorized_keys щоб це працювало?
Tomáš Blatný

Він повинен працювати так само. Ви виконували б аутентифікацію за допомогою ключа і до тих пір, поки оболонка буде встановлена ​​на сценарій для віддаленого облікового запису, що знаходиться у файлі / etc / passwd віддаленого сервера, сценарій буде виконаний. Незабаром я додаду знімок екрана до мого повідомлення.
NotAdmin Dave

1
@Dave не може чекати вашої книги
Burgi

Спасибі за вашу відповідь, це не вирішило моєї проблеми, але було для мене найцікавішим і фактично вирішило інші проблеми, які я мав. Дав вам щедрість, спасибі ще раз
Tomáš Blatný

4

The 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

ITYM " Примітка одинарні лапки "не" ні ".
dave_thompson_085

@ dave_thompson_085 насправді я зробив, спасибі.
terdon

Насправді я використовую повні шляхи всюди, як я вже згадував у своєму питанні, повідомляється про помилку всередині composer install команду, яку я, очевидно, не можемо змінити. Також $PATH це нормально, як я вже згадував у моєму питанні теж, я перевірив всі речі, додавши їх у скрипт і працюючи віддалено через ssh login. Також не можу перевірити ssh deployer@XXX.com 'echo $PATH' як ви стверджували, оскільки мій ssh ​​логін обмежується тільки одним сценарієм, але я перевірив його, коли я додаю $ PATH до цього сценарію (зазначено вище). env річ
Tomáš Blatný

@ TomášBlatný добре, ви використовуєте ENV де-небудь, або ви не будете бачити цю помилку. Я не знаю композитора, але вам, мабуть, доведеться скопіювати чи пов'язати виконуваний файл php з каталогом на його шляху. Такі речі важко налагоджувати, оскільки в кожному випадку так багато речей залежить від іншого.
terdon

Це правда, env насправді називається всередині композитора. Але це не вирішує проблему, чому деякі виклики композитора проходять, а деякі ні. Проте я буду далі досліджувати це, вивчаючи його код. Дякую за ваш час
Tomáš Blatný

2

Чи можливо це bash потрібно скинути до своєї хеш-таблиці?

Якщо так, ви можете спробувати додати hash -r десь у вашому сценарії, який змушує оболонку переглядати $PATH знову замість того, щоб покладатися на (можливо, застарілу) інформацію з хеш-таблиці.

Коли потрібно, hash також може дозволити оболонці запам'ятовувати шляхи до виконуваних файлів, встановлених у нестандартних місцях, використовуючи -p або забудьте шляхи з -d опції.

Джерела:

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


Це не вирішило проблему для мене, але її хороші знання, тому я додав вам +1
Tomáš Blatný

1

Схоже, можливо, вам потрібно додати php до вашого шляху. Спробуйте:

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

Ви також можете перевірити, де живе ваш php, щоб переконатися, що шлях є правильним. Спробуйте:

which php

Ну, це не проблема, оскільки php -v виводить правильну версію PHP і composer --version виводить версію композитора. Як я вже сказав, проблема полягає тільки в одній команді.
Tomáš Blatný

1

Зрозуміло, що у вас є проблема, оскільки ваш сценарій розгортання не може знайти речей, які безумовно знаходяться на шляху, коли ви робите звичайний ssh ​​login.

Перше, що потрібно зробити, щоб підтвердити, що виникли проблеми з 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 daemon ... який, ймовірно, відрізняється від вашого середовища як зареєстрованого користувача.

Сторінка для авторизованих ключів охоплює те, що відбувається після аутентифікації. Щодо середовища:

  1. Читає файл ~ / .ssh / середовище, якщо воно існує, і користувачі               змінити своє середовище. Див               Параметр PermitUserEnvironment у sshd_config (5).

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

~/.ssh/environment Формат також вказаний на сторінці man.

         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. Детальнішу інформацію див.


Що стосується Without knowing exactly how you have setup your deploy script to run: у моєму питанні на початку, є посилання, як я його налаштував (використовуючи ~/.ssh/authorized_keys. Спасибі за пораду з командою оновлення, я спробував, але на жаль, без різниці. Проте, я продовжуватиму це досліджувати і пробувати різні снаряди. Прийміть +1 для цієї ідеї.
Tomáš Blatný

Ви спробували оновити сценарій розгортання, щоб роздрукувати поточний $ PATH? Не могли б ви опублікувати результат? Якщо це не відповідає очікуваному, можна просто спробувати налаштувати PATH явно, як я запропонував на початку вашого сценарію розгортання.
mattpr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.