web-dev-qa-db-fra.com

/ usr / bin / env: php: Aucun fichier ou répertoire de ce type

Je souhaite utiliser le script .sh pour le déploiement de mon application. Ce script est sur mon serveur domestique (serveur Ubuntu 15.10), marqué comme exécutable. L'accès à ce script se fait via ssh, en utilisant ce tutoriel , j'ai configuré la connexion ssh, qui exécute ce script. Donc, fondamentalement, j'appelle simplement ssh [email protected] someArguments et il exécute mon script avec someArguments en tant que paramètres. L'utilisateur deployer a uid = 0, c'est donc fondamentalement root (cela sera modifié à l'avenir, je ne l'ai défini que pour éliminer les problèmes d'autorisations jusqu'à ce que tout fonctionne correctement).

Et voici où les choses deviennent difficiles. Le script indique /usr/bin/env: php: No such file or directory à la commande /bin/composer install (utilisant Composer ). Les choses sont plus étranges plus je regarde ce script. Avant cette ligne, il est également appelé /bin/composer self-update et /bin/composer -V, qui s'exécutent correctement et affichent une sortie correcte.

J'ai vérifié les choses suivantes:

  • /usr/bin/env php -v affiche la version correcte PHP (identique à /usr/bin/php -v)
  • whereis php affiche php: /usr/bin/php /usr/local/bin/php /usr/share/man/man1/php.1.gz
  • Le package php5-cli est installé et la dernière version
  • $PATH contient /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
  • which env affiche /usr/bin/env

J'ai aussi essayé les choses suivantes:

  • exécuter le script directement en tant que bash deploy.sh sous la racine (puisqu'il est identique à cet utilisateur) - fonctionne parfaitement sans erreur
  • exécuter directement les commandes qui échouent - aussi parfaitement sans erreurs

Cela me semble donc être un cas très spécifique, pourquoi cette commande ne fonctionne pas. J'ai passé 12 heures à le déboguer et je suis à court d'idées ici.

PS: Une erreur similaire (/usr/bin/env: node: No such file or directory) se produit lorsqu'il y a bower install (using Bower ), mais pas lors de l'exécution de npm install (avec NPM ).

9
Tomáš Blatný

Assurez-vous que les fins de ligne et/ou les espaces invisibles ne causent pas le problème.

Supprimez les espaces de la première ligne du script et insérez-en de nouveaux, en veillant à ne pas maintenir la touche CTRL enfoncée tout en appuyant sur la touche espace.

Assurez-vous également que vous n'avez pas de fins de ligne DOS (CR + LF). Voir https://stackoverflow.com/questions/82726/convert-dos-line-endings-to-linux-line-endings-in-vim pour plus de détails.

5
neuhaus

Le moyen le plus simple .... changez le shell de l'utilisateur en tant que script.

/ etc/passwd

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

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

Exemple de script (assurez-vous que le bit d'exécution est défini sur chmod + x)

/scripts/deploy.sh

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

Sample Fonctionne à chaque fois! Vous devriez même pouvoir utiliser le script pour dépanner/déboguer les variables d’environnement que vous croyez être non définies, etc.

Remarque: Il est recommandé de toujours QUALIFIER COMPLÈTE les chemins d'accès aux scripts, aux exécutables, etc. )

C'était facile .. Merci d'avoir posté ..

Référence: /etc/passwd format

4
NotAdmin Dave

La commande env va parcourir le $PATH de l'utilisateur pour trouver le premier exécutable du nom donné. Donc, /usr/bin/env php cherchera un fichier exécutable appelé php dans l’un des répertoires du $PATH de l’utilisateur qui l’exécute.

Dans votre cas, cela est certainement dû au fait que lorsque vous exécutez une commande sur ssh, vous ne démarrez pas un shell complet et ne lisez pas les fichiers d'initialisation de votre shell. Vous pouvez vérifier cela en exécutant cette commande (notez les guillemets simples):

ssh [email protected] 'echo $PATH'

Et en comparant la sortie à ce que vous obtenez si vous ssh [email protected] et , alors exécutez echo $PATH. Sur mon système. par exemple:

$ 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

Par conséquent, le $PATH auquel votre script a accès lorsqu’il est exécuté avec ssh [email protected] n’est pas le même que lorsque vous vous connectez pour le tester.

Dans tous les cas, la solution simple consiste à utiliser le chemin complet de l'interpréteur au lieu de env. Les chemins env et complet ont tous les deux leurs avantages et inconvénients mais, dans ce cas, le chemin est plus sûr:

#!/usr/bin/php
4
terdon

Est-il possible que bash nécessite une réinitialisation de sa table de hachage?

Si tel est le cas, vous pouvez essayer d'ajouter hash -r quelque part dans votre script, ce qui oblige le shell à parcourir à nouveau $PATH plutôt que de se fier aux informations (éventuellement obsolètes) de la table de hachage.

Si nécessaire, hash peut également permettre au shell de mémoriser les chemins d'accès aux exécutables installés dans des emplacements non standard à l'aide de l'option -p, ou d'oublier les chemins d'accès avec l'option -d.

Sources:

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

2
flyingfinger

On dirait que vous devez peut-être ajouter php à votre chemin. Essayer:

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

Vous pouvez également vouloir vérifier où habite votre php pour être sûr que le chemin y est correct. Essayer:

which php
1
Jeramy

Il est clair que vous rencontrez un problème de chemin puisque votre script de déploiement ne trouve pas les éléments qui se trouvent définitivement sur le chemin lorsque vous vous connectez au format SSH normal.

La première chose à faire pour vous assurer que vous avez un problème avec PATH consiste à mettre à jour votre script de déploiement afin de consigner la sortie de env ou au moins echo $PATH. Je suppose que la manière dont votre script de déploiement s'appelle, $ PATH n'est pas définie comme vous le souhaiteriez. Cette sortie de débogage confirmera/infirmera ma théorie.

J'ai regardé le tutoriel que vous avez suivi. Vous devriez probablement vous assurer lors de la mise à jour que le command= soit command="/bin/sh /path/to/your/script..." si vous n'avez pas encore vérifié que votre script est exécuté par le bon shell.

Si vous avez un problème avec PATH, une solution rapide/incorrecte consiste simplement à définir explicitement PATH au début de votre script de déploiement.

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

Explication détaillée et autres options ...

Sur Linux, lorsque les commandes sont exécutées, elles héritent de l'environnement de leur processus parent.

Lorsque vous vous connectez en tant qu'utilisateur normal via SSH, des événements se produisent (par exemple, l'exécution de/etc/bashrc/etc/profile ~/.bash_profile ~/.bashrc, etc.). À ce stade, vous avez peut-être mis à jour l'environnement de votre processus en effectuant des opérations comme export PATH="$PATH:~/mybin" dans ces scripts. Désormais, tous les processus que vous exécuterez hériteront de votre environnement actuel.

Exécuter une commande au lieu d'obtenir un identifiant de connexion Shell signifie que cette commande est exécutée par le démon ssh et héritera de l'environnement du processus du démon ssh ... qui est probablement différent de votre environnement en tant qu'utilisateur connecté.

La page de manuel des clés autorisées couvre ce qui se passe après l'authentification. Concernant l'environnement:

  1. Lit le fichier ~/.ssh/environment, s'il existe, et les utilisateurs sont autorisés à modifier leur environnement. Voir l'option PermitUserEnvironment dans sshd_config (5).

Par conséquent, l'emplacement approprié pour configurer l'environnement pour le processus est dans ~/.ssh/environment, où ~ est le répertoire de base de l'utilisateur authentifié pour exécuter la commande. Vous devez également vérifier votre sshd_config pour vous assurer que PermitUserEnvironment est autorisé.

Le format ~/.ssh/environment est également spécifié dans la page de manuel de cours.

         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.

Une autre façon de spécifier l'environnement sans utiliser la méthode mentionnée ci-dessus consiste à utiliser l'option environment="NAME=value" dans le fichier allowed_keys. Voir la page de manuel que j'ai liée ci-dessus pour plus de détails.

1
mattpr