/ usr / bin / env: php: nessun file o directory


9

Voglio usare lo script .sh per la distribuzione della mia app. Quello script è sul mio server di casa (Ubuntu 15.10 Server), contrassegnato come eseguibile. L'accesso a questo script avviene tramite ssh, utilizzando questo tutorial, ho impostato il login ssh, che esegue quello script. Quindi, fondamentalmente, ho appena chiamato ssh deployer@XXX.com someArgumentsed esegue il mio script con someArgumentsparametri. L'utente deployerha uid = 0, quindi è fondamentalmente root(questo verrà modificato in futuro, l'ho impostato solo per eliminare i problemi di autorizzazione fino a quando non funziona correttamente).

Ed ecco dove le cose si complicano. Lo script riporta /usr/bin/env: php: No such file or directorya comando /bin/composer install(usando Composer ). Le cose sono più strane più guardo su quella sceneggiatura. Prima di questa riga, viene anche chiamato /bin/composer self-updatee /bin/composer -V, che viene eseguito correttamente e visualizza l'output corretto.

Ho verificato le seguenti cose:

  • /usr/bin/env php -vmostra la versione corretta di PHP (uguale a /usr/bin/php -v)
  • whereis php visualizza php: /usr/bin/php /usr/local/bin/php /usr/share/man/man1/php.1.gz
  • php5-cli il pacchetto è installato e la versione più recente
  • $PATH contiene /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
  • which env visualizza /usr/bin/env

Ho anche provato le seguenti cose:

  • eseguire lo script direttamente come bash deploy.shsotto root (poiché è lo stesso di quell'utente) - funziona perfettamente senza errori
  • esecuzione diretta di comandi non riusciti - anche perfettamente senza errori

Quindi questo mi sembra un caso molto specifico, perché questo comando non funziona. Ho trascorso 12 ore a eseguire il debug e non ho idee qui.

PS: errore simile ( /usr/bin/env: node: No such file or directory) si verifica quando è presente bower install(utilizzando Bower ), ma non durante l'esecuzione npm install(utilizzando NPM ).


Esegui sh deployinvece di bash deploy(forse un po 'di bashismo). Come hai controllato le " seguenti cose "? Consiglio di controllarli nello script, in modo da poter scoprire eventuali sostituzioni e risanamenti di envs.
Giacomo Catenazzi,

per quanto riguarda " seguenti cose ": le ho aggiunte all'inizio dello script deploy.sh e hanno prodotto queste cose che ho messo in discussione. Lo stesso risultato è quando li eseguo da solo, però.
Tomáš Blatný,

sh deployed bash deployentrambi danno gli stessi risultati
Tomáš Blatný,

Mostra quella linea qui, per favore. Ti consiglio di sostituire il tuo comando php su questa riga nel tuo script con l'output in file per esaminare le variabili di ambiente al momento della chiamata / usr / bin / env:/usr/bin/env > environment.txt
Oleg Bolden,

Risposte:


6

Assicurati che il problema non sia causato dalle terminazioni di riga e / o dagli spazi invisibili.

Rimuovere gli spazi nella prima riga dello script e inserirne di nuovi, assicurandosi di non tenere premuto CTRL mentre si preme spazio.

Inoltre, assicurati di non avere terminazioni di riga DOS (CR + LF). Vedi /programming/82726/convert-dos-line-endings-to-linux-line-endings-in-vim per i dettagli.


Sto usando IDE, che controlla automaticamente (e converte) solo CR + LF in LF, rimuove la distinta base e si preoccupa dei caratteri bianchi, ma l'ho ricontrollato e sembra ok (comunque non funziona ancora). Grazie comunque
Tomáš Blatný

4

Il modo più semplice .... cambia la shell dell'utente come script.

/ Etc / passwd

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

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

Script di esempio (assicurarsi che il bit di esecuzione sia impostato chmod + x)

/scripts/deploy.sh

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

Campione Funziona sempre! Dovresti anche essere in grado di utilizzare lo script per risolvere / eseguire il debug di qualsiasi variabile env che potresti ritenere non impostata, ecc ... funzioneranno anche gli argomenti di gestione passati in ssh.

Nota: si consiglia di QUALIFICARE sempre COMPLETAMENTE i percorsi per eventuali script, file eseguibili, ecc. Sopra c'è solo un esempio che consente di impostare il percorso predefinito per chiamare moo.sh all'interno della cartella moo;)

È stato facile .. Grazie per la pubblicazione ..

Riferimento: formato / etc / passwd


Bella risposta, ma in realtà non uso mai l'utente direttamente sul server, vado sempre sshal server e, per corsia authorized_keys, lo script viene chiamato e quindi la connessione termina. Come devo modificare authorized_keysper farlo funzionare?
Tomáš Blatný

Dovrebbe funzionare allo stesso modo. Verrai autenticato tramite chiave e fintanto che la shell è impostata sullo script per l'account remoto in questione all'interno del file / etc / passwd del server remoto, lo script verrà eseguito. Aggiungerò uno screenshot al mio post a breve.
NotAdmin Dave,

1
@Dave non vede l'ora che arrivi il tuo libro
Burgi

Grazie per la tua risposta, non ha risolto il mio problema, ma è stato per me il più interessante e in realtà ha risolto altri problemi che ho avuto. Ti
ho

4

Il envcomando esaminerà un utente $PATHper trovare il primo eseguibile con il nome indicato. Quindi, /usr/bin/env phpcercherà un file eseguibile chiamato phpin una qualsiasi delle directory $PATHdell'utente che lo esegue.

Nel tuo caso, questo è quasi certamente perché quando si esegue un comando ssh, non si avvia una shell completa e non si legge effettivamente i file di inizializzazione della shell. Puoi verificarlo eseguendo questo comando (nota le virgolette singole):

ssh deployer@XXX.com 'echo $PATH'

E confrontando l'output con quello che ottieni se ssh deployer@XXX.come poi corri echo $PATH. Sul mio sistema. per esempio:

$ 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

Pertanto, $PATHciò a cui lo script ha accesso quando eseguito con ssh deployer@XXX.comnon è lo stesso di quando si accede per testarlo.

In ogni caso, la soluzione semplice è utilizzare il percorso completo per l'interprete anziché env. Entrambi envi percorsi completi hanno i loro vantaggi e svantaggi ma, in questo caso, il percorso è più sicuro:

#!/usr/bin/php

ITYM " nota le virgolette singole" non " non ".
dave_thompson_085

@ dave_thompson_085 in effetti l'ho fatto, grazie.
terdon,

In realtà sto usando percorsi completi ovunque, come ho già detto nella mia domanda, l'errore è riportato all'interno del composer install comando, che ovviamente non posso modificare. Inoltre $PATHva bene, come ho già detto nella mia domanda, ho controllato tutte le cose aggiungendole allo script ed eseguendo in remoto tramite login ssh. Inoltre non posso controllare ssh deployer@XXX.com 'echo $PATH'come hai dichiarato, poiché il mio login ssh è limitato a un solo script, ma ho controllato hoververlo quando ho aggiunto $ PATH a quello script (indicato sopra) Comunque, grazie per la tua risposta e accetto + 1 per avermi spiegato la envcosa
Tomáš Blatný

@ TomášBlatný bene, stai usando env da qualche parte, o non vedresti quell'errore. Non conosco il compositore ma probabilmente dovrai copiare o collegare l'eseguibile php a una directory nel suo percorso. È difficile eseguire il debug di questo tipo di cose poiché ci sono così tante cose ciascuna a seconda dell'altra.
terdon,

Questo è vero, in envrealtà è chiamato all'interno del compositore. Ma questo non risolve il problema, perché alcune chiamate del compositore passano e altre no. Tuttavia, approfondirò ulteriormente questo aspetto esaminando il suo codice. Grazie per il tuo tempo
Tomáš Blatný

2

È possibile che sia bashnecessario ripristinare la sua tabella hash?

In tal caso, potresti provare ad aggiungere hash -rda qualche parte nel tuo script, il che forza la shell a riesaminare $PATHpiuttosto che fare affidamento su informazioni (probabilmente obsolete) dalla tabella hash.

Se necessario, hashè anche possibile abilitare la shell a ricordare i percorsi degli eseguibili installati in posizioni non standard usando l' -popzione, oppure dimenticare i percorsi con l' -dopzione.

fonti:

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


Questo non ha risolto il problema per me, tuttavia è una buona conoscenza, quindi ti ho aggiunto un +1
Tomáš Blatný

1

Sembra che forse devi aggiungere php al tuo percorso. Provare:

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

Potresti anche voler controllare dove vive il tuo php per essere sicuro che il percorso sia corretto. Provare:

which php

Bene, questo non è il problema, poiché php -vgenera la versione corretta di PHP e composer --versiongenera la versione del compositore. Come ho detto, il problema è solo in un comando.
Tomáš Blatný

1

È chiaro che hai un problema di percorso poiché il tuo script deploy non riesce a trovare cose che sono sicuramente sul percorso quando esegui un normale accesso ssh.

La prima cosa da fare per confermare che hai un problema PATH è aggiornare lo script di distribuzione per registrare l'output envo almeno echo $PATH. Immagino che il modo in cui viene chiamato il tuo script deploy, $ PATH non è impostato come ti aspetteresti. Questo output di debug confermerà / smentirà la mia teoria.

Ho visto il tutorial che hai seguito. Probabilmente dovresti assicurarti di aggiornare il command=fatto command="/bin/sh /path/to/your/script..."se non sei già sicuro che il tuo script sia eseguito dalla shell giusta.

Se si riscontra un problema PATH, una soluzione rapida / sporca consiste solo nell'impostare esplicitamente PATH all'inizio dello script di distribuzione.

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

Spiegazione dettagliata e ulteriori opzioni ...

Su Linux quando i comandi vengono eseguiti ereditano l'ambiente del loro processo genitore.

Quando accedi come un normale utente tramite SSH ci sono cose che accadono (come eseguire / etc / bashrc / etc / profile ~ / .bash_profile ~ / .bashrc ecc.). A quel punto potresti aver aggiornato l'ambiente del tuo processo facendo cose come export PATH="$PATH:~/mybin"quelle di quegli script. Ora tutti i processi futuri che eseguirai erediteranno il tuo ambiente attuale.

L'esecuzione di un comando invece di ottenere una shell di accesso significa che il comando viene eseguito dal demone ssh e erediterà l'ambiente del processo demone ssh ... che è probabilmente diverso dal proprio ambiente come utente connesso.

La pagina man per le chiavi autorizzate copre ciò che accade dopo l'autenticazione. Per quanto riguarda l'ambiente:

  1. Legge il file ~ / .ssh / environment, se esiste, e gli utenti sono autorizzati a cambiare il loro ambiente. Vedi l'opzione PermitUserEnvironment in sshd_config (5).

Quindi il posto appropriato per configurare l'ambiente per il processo è ~/.ssh/environmentdove si ~trova la home directory per l'utente che è autenticato per eseguire il comando. È inoltre necessario controllare sshd_config per assicurarsi che PermitUserEnvironment sia consentito.

~/.ssh/environment il formato è anche specificato nella pagina man ovviamente.

         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.

Un modo alternativo per specificare l'ambiente senza utilizzare il metodo sopra menzionato è utilizzare l' environment="NAME=value"opzione nel file authorized_keys. Vedi la pagina man che ho linkato sopra per i dettagli.


Per quanto riguarda Without knowing exactly how you have setup your deploy script to run: all'inizio della mia domanda, c'è un link, come l'ho impostato (usando ~/.ssh/authorized_keys. Grazie per il suggerimento con il comando di aggiornamento, l'ho provato, ma sfortunatamente senza differenze. Cercherò comunque di indagare ulteriormente e provare diverse shell Si prega di accettare un +1 per questa idea
Tomáš Blatný

Hai provato ad aggiornare lo script di distribuzione per stampare l'attuale $ PATH? Potresti pubblicare il risultato? Se non corrisponde a quello che ti aspetti, puoi semplicemente provare a impostare il PERCORSO in modo esplicito, come ho suggerito all'inizio dello script di distribuzione.
Mattpr
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.