/ usr / bin / env: php: no existe tal archivo o directorio

9

Quiero usar el script .sh para la implementación de mi aplicación. Ese script está en mi servidor doméstico (Ubuntu 15.10 Server), marcado como ejecutable. El acceso a este script se realiza a través de ssh, utilizando este tutorial, he configurado ssh login, que ejecuta ese script. Básicamente, solo llamo ssh [email protected] someArgumentsy ejecuta mi script con someArgumentsparámetros. El usuario deployertiene uid = 0, por lo que es básicamente root(esto cambiará en el futuro, lo configuré solo para eliminar los problemas de permisos hasta que funcione bien).

Y aquí es donde las cosas se ponen difíciles. El script informa /usr/bin/env: php: No such file or directoryen el comando /bin/composer install(usando Composer ). Las cosas son más raras cuanto más miro ese guión. Antes de esta línea, también se llama /bin/composer self-updatey /bin/composer -V, que se ejecuta correctamente y muestra la salida correcta.

He comprobado las siguientes cosas:

  • /usr/bin/env php -vmuestra la versión correcta de PHP (igual que /usr/bin/php -v)
  • whereis php muestra php: /usr/bin/php /usr/local/bin/php /usr/share/man/man1/php.1.gz
  • php5-cli el paquete está instalado y la versión más nueva
  • $PATH contiene /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
  • which env muestra /usr/bin/env

También he intentado lo siguiente:

  • Ejecutar el script directamente como bash deploy.shroot (ya que es el mismo que el usuario): funciona perfectamente sin errores
  • ejecutar comandos fallidos directamente, también perfectamente sin errores

Esto me parece un caso muy específico, por qué este comando no funciona. Pasé 12 horas depurándolo y no tengo ideas aquí.

PD: Se /usr/bin/env: node: No such file or directoryproduce un error similar ( ) cuando hay bower install(usando Bower ), pero no cuando se ejecuta npm install(usando NPM ).

Tomáš Blatný
fuente
Corre en sh deploylugar de bash deploy(quizás algo de bashism). ¿Cómo comprobaste las " cosas siguientes "? Recomiendo verificarlos en el script, para que pueda descubrir eventuales anulaciones y desinfecciones de envs.
Giacomo Catenazzi
con respecto a " cosas siguientes ": las agregué al inicio del script deploy.sh y generan estas cosas que puse en duda. Sin embargo, la misma salida es cuando los ejecuto solo.
Tomáš Blatný
sh deployy bash deployambos dan los mismos resultados
Tomáš Blatný
Muestra esa línea aquí, por favor. Le recomiendo que reemplace su comando php en esta línea en su script con salida a archivo para examinar las variables de entorno al momento de llamar a / usr / bin / env:/usr/bin/env > environment.txt
Oleg Bolden

Respuestas:

6

Asegúrese de que los finales de línea y / o espacios invisibles no estén causando el problema.

Elimine los espacios en la primera línea del script e inserte otros nuevos, asegurándose de no mantener presionada la tecla CTRL mientras presiona la barra espaciadora.

Además, asegúrese de no tener terminaciones de línea de DOS (CR + LF). Ver /programming/82726/convert-dos-line-endings-to-linux-line-endings-in-vim para más detalles.

Neuhaus
fuente
Estoy usando IDE, que verifica automáticamente (y convierte) CR + LF a LF solamente, elimina la lista de materiales y se preocupa por los caracteres blancos, pero lo verifiqué dos veces y parece estar bien (aunque todavía no funciona). Gracias de todos modos
Tomáš Blatný
4

La forma más fácil ... cambia el shell del usuario como el script.

/ etc / passwd

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

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

Script de ejemplo (asegúrese de que el bit de ejecución esté configurado chmod + x)

/scripts/deploy.sh

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

Muestra ¡Funciona siempre! Incluso debería poder usar el script para solucionar problemas / depurar cualquier variable env que pueda sentir que no está configurada, etc. También funcionarán los argumentos de manejo que se pasan a ssh.

Nota: Su mejor práctica es CALIFICAR siempre TOTALMENTE las rutas para cualquier script, ejecutable, etc. Lo anterior es solo un ejemplo que permite configurar la ruta predeterminada para llamar a moo.sh dentro de la carpeta moo;)

Eso fue fácil ... Gracias por publicar ...

Referencia: / etc / passwd format

NotAdmin Dave
fuente
Buena respuesta, pero en realidad nunca uso al usuario en el servidor directamente, siempre sshen el servidor, y por carril authorized_keys, se llama al script y luego termina la conexión. ¿Cómo debo modificar authorized_keyspara mantener esto funcionando?
Tomáš Blatný
Debería funcionar igual. Debería autenticarse mediante la clave y siempre que el shell esté configurado en el script para la cuenta remota en cuestión dentro del archivo / etc / passwd del servidor remoto, el script se ejecutará. Agregaré una captura de pantalla a mi publicación en breve.
NotAdmin Dave
1
@Dave no puede esperar su libro
Burgi
Gracias por su respuesta, no resolvió mi problema, pero fue para mí el más interesante y resolvió otros problemas que tuve. Te di la recompensa, gracias de nuevo
Tomáš Blatný
4

El envcomando buscará a través de un usuario $PATHpara encontrar el primer ejecutable del nombre dado. Por lo tanto, /usr/bin/env phpbuscará un archivo ejecutable llamado phpen cualquiera de los directorios $PATHdel usuario que lo ejecuta.

En su caso, eso es casi seguro porque cuando ejecuta un comando ssh, no inicia un shell completo y en realidad no lee los archivos de inicialización de su shell. Puede verificar esto ejecutando este comando (tenga en cuenta las comillas simples):

ssh deployer@XXX.com 'echo $PATH'

Y comparando la salida con lo que obtienes si tú ssh [email protected]y luego corres echo $PATH. En mi sistema por ejemplo:

$ 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

Por lo tanto, el $PATHacceso al script al ejecutarlo ssh [email protected]no es el mismo que cuando inicia sesión para probarlo.

En cualquier caso, la solución simple es utilizar la ruta completa al intérprete en lugar de env. Ambas envy las rutas completas tienen sus ventajas e inconvenientes , pero, en este caso, la ruta es más segura:

#!/usr/bin/php
terdon
fuente
ITYM " tenga en cuenta las comillas simples" no " no ".
dave_thompson_085
@ dave_thompson_085 de hecho lo hice, gracias.
terdon
De hecho, estoy usando rutas completas en todas partes, como mencioné en mi pregunta, el error se informa dentro del composer install comando, que obviamente no puedo modificar. También $PATHestá bien, como mencioné en mi pregunta también, verifiqué todas las cosas agregándolas al script y ejecutándolas de forma remota a través de ssh login Además, no puedo verificar lo ssh [email protected] 'echo $PATH'que dijiste, ya que mi inicio de sesión ssh se limita a un solo script, pero lo comprobé cuando agregué $ PATH a ese script (indicado anteriormente) De todos modos, gracias por tu respuesta y acepta + 1 por explicarme la envcosa
Tomáš Blatný
@ TomášBlatný bueno, estás usando env en alguna parte, o no verías ese error. No sé compositor, pero probablemente tendrá que copiar o vincular el ejecutable php a un directorio en su ruta. Este tipo de cosas es difícil de depurar ya que hay tantas cosas cada una dependiendo de la otra.
terdon
Eso es cierto, en envrealidad se llama compositor interno. Pero esto no resuelve el problema, por qué algunas llamadas de compositor pasan y otras no. Sin embargo, investigaré esto más a fondo buscando en su código. Gracias por su tiempo
Tomáš Blatný
2

¿Es posible que bashnecesite restablecer su tabla hash?

Si es así, puede intentar agregar hash -ren algún lugar de su script, lo que obliga al shell a revisar $PATHnuevamente en lugar de confiar en la información (posiblemente desactualizada) de la tabla hash.

Cuando sea necesario, hashtambién puede habilitar el shell para recordar rutas a ejecutables instalados en ubicaciones no estándar utilizando la -popción, u olvidar rutas con la -dopción.

Fuentes:

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

Flyingfinger
fuente
Esto no resolvió el problema para mí, sin embargo, es un buen conocimiento, así que le agregué un +1
Tomáš Blatný
1

Parece que tal vez necesites agregar php a tu camino. Tratar:

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

También es posible que desee verificar dónde vive su php para asegurarse de que la ruta allí sea correcta. Tratar:

which php
Jeramy
fuente
Bueno, este no es el problema, ya que php -vgenera la versión correcta de PHP y la composer --versionversión del compositor. Como dije, el problema está en un solo comando.
Tomáš Blatný
1

Está claro que tiene un problema de ruta ya que su script de implementación no puede encontrar cosas que definitivamente están en la ruta cuando realiza un inicio de sesión ssh normal.

Lo primero que debe hacer para confirmar que tiene un problema de RUTA es actualizar su script de implementación para registrar la salida de, envo al menos echo $PATH. Supongo que por la forma en que se llama el script de implementación, $ PATH no está configurado como cabría esperar. Esta salida de depuración confirmará / negará mi teoría.

Miré el tutorial que seguiste. Probablemente debería asegurarse en la actualización command=de ser command="/bin/sh /path/to/your/script..."si aún no se ha asegurado de que su script se ejecute en el shell correcto.

Si tiene un problema de RUTA, una solución rápida / sucia es establecer explícitamente RUTA al comienzo de su script de implementación.

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

Explicación detallada y más opciones ...

En Linux, cuando se ejecutan comandos, heredan el entorno de su proceso padre.

Cuando inicia sesión como usuario normal a través de SSH, suceden cosas (como ejecutar / etc / bashrc / etc / profile ~ / .bash_profile ~ / .bashrc, etc.). En ese momento, es posible que haya actualizado el entorno de su proceso haciendo cosas como export PATH="$PATH:~/mybin"en esos scripts. Ahora, cualquier proceso futuro que ejecute heredará su entorno actual.

Ejecutar un comando en lugar de obtener un shell de inicio de sesión significa que el comando es ejecutado por ssh daemon y heredará el entorno del proceso ssh daemon ... que probablemente sea diferente de su entorno como usuario conectado.

La página de manual para claves autorizadas cubre lo que sucede después de la autenticación. En cuanto al medio ambiente:

  1. Lee el archivo ~ / .ssh / environment, si existe, y los usuarios pueden cambiar su entorno. Vea la opción PermitUserEnvironment en sshd_config (5).

Entonces, el lugar apropiado para configurar el entorno para el proceso es ~/.ssh/environmentdónde ~está el directorio de inicio para el usuario que está autenticado para ejecutar el comando. También debe verificar su sshd_config para asegurarse de que PermitUserEnvironment esté permitido.

~/.ssh/environment el formato también se especifica en la página del manual, por supuesto.

         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.

Una forma alternativa de especificar el entorno sin utilizar el método mencionado anteriormente es utilizar la environment="NAME=value"opción en el archivo autorizado_claves. Consulte la página del manual que he vinculado anteriormente para obtener más detalles.

mattpr
fuente
En cuanto a Without knowing exactly how you have setup your deploy script to run: en mi pregunta al principio, hay un enlace, cómo lo configuré (usando ~/.ssh/authorized_keys. Gracias por el consejo con el comando de actualización, lo probé, pero desafortunadamente sin ninguna diferencia. Sin embargo, investigaré esto y probaré diferentes shells . Acepte un +1 para esa idea.
Tomáš Blatný
¿Intentó actualizar su script de implementación para imprimir el $ PATH actual? ¿Podrías publicar el resultado? Si no coincide con lo que espera, puede intentar configurar la RUTA explícitamente como sugerí al comienzo de su script de implementación.
mattpr