/ usr / bin / env: php: Esse arquivo ou diretório não existe

9

Quero usar o script .sh para a implantação do meu aplicativo. Esse script está no meu servidor doméstico (Ubuntu 15.10 Server), marcado como executável. O acesso a esse script é feito através do ssh, usando este tutorial, eu configurei o login do ssh, que executa esse script. Então, basicamente, eu apenas chamo ssh [email protected] someArgumentse ele executa meu script com someArgumentscomo parâmetros. O usuário deployertem uid = 0, então é basicamente root(isso será alterado no futuro, eu o configurei apenas para eliminar problemas de permissões até que funcione bem).

E aqui é onde as coisas ficam complicadas. O script relata /usr/bin/env: php: No such file or directoryno comando /bin/composer install(usando o Composer ). As coisas são mais estranhas quanto mais eu olho nesse script. Antes dessa linha, também é chamado /bin/composer self-updatee /bin/composer -V, que funciona corretamente e exibe a saída correta.

Eu verifiquei as seguintes coisas:

  • /usr/bin/env php -vexibe a versão correta do PHP (igual a /usr/bin/php -v)
  • whereis php exibe php: /usr/bin/php /usr/local/bin/php /usr/share/man/man1/php.1.gz
  • php5-cli pacote está instalado e a versão mais recente
  • $PATH contém /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
  • which env exibe /usr/bin/env

Eu também tentei seguir as seguintes coisas:

  • executar o script diretamente como bash deploy.shroot (já que é o mesmo usuário) - funciona perfeitamente sem erros
  • executando comandos com falha diretamente - também perfeitamente sem erros

Portanto, isso me parece um caso muito específico, por que esse comando não funciona. Passei 12 horas depurando-o e estou sem ideias aqui.

PS: Erro semelhante ( /usr/bin/env: node: No such file or directory) ocorre quando existe bower install(usando o Bower ), mas não durante a execução npm install(usando o NPM ).

Tomáš Blatný
fonte
Corra em sh deployvez de bash deploy(talvez algum basismo). Como você checou as " seguintes coisas "? Eu recomendo verificá-los no script, para que você possa descobrir eventuais substituições e saneamentos de envs.
Giacomo Catenazzi 26/03
sobre "as seguintes coisas ": adicionei-as ao início do script deploy.sh e elas produzem essas coisas que coloco em questão. A mesma saída é quando eu os executo sozinhos.
Tomáš Blatný 26/03
sh deploye bash deploytanto dá mesmos resultados
Tomáš Blatny
Mostre essa linha aqui, por favor. Eu recomendo que você substitua seu php comando nesta linha em seu script com saída para o arquivo para examinar as variáveis de ambiente no momento da chamada / usr / bin / env:/usr/bin/env > environment.txt
Oleg Bolden

Respostas:

6

Verifique se as terminações de linha e / ou espaços invisíveis não estão causando o problema.

Remova os espaços na primeira linha do script e insira novos, certificando-se de não segurar a tecla CTRL enquanto pressiona o espaço.

Além disso, verifique se você não possui terminações de linha do DOS (CR + LF). Consulte /programming/82726/convert-dos-line-endings-to-linux-line-endings-in-vim para obter detalhes.

Neuhaus
fonte
Estou usando o IDE, que verifica automaticamente (e converte) apenas CR + LF para LF, remove a lista técnica e se preocupa com caracteres em branco, mas verifiquei duas vezes e parece bom (ainda não está funcionando). Obrigado de qualquer forma
Tomáš Blatny
4

Maneira mais fácil .... altere o shell do usuário como o script.

/ etc / passwd

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

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

Script de exemplo (verifique se o bit de execução está definido chmod + x)

/scripts/deploy.sh

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

Amostra Funciona sempre! Você deve ser capaz de usar o script para solucionar problemas / depurar quaisquer variáveis ​​env que você considere não configuradas, etc ... também os argumentos de manipulação passados ​​para o ssh também funcionarão.

Nota: É uma boa prática sempre QUALIFICAR TOTALMENTE os caminhos de quaisquer scripts, executáveis, etc. Acima, é apenas um exemplo que permite que o caminho padrão seja definido para chamar moo.sh na pasta moo;)

Isso foi fácil .. Obrigado por postar ..

Referência: formato / etc / passwd

NotAdmin Dave
fonte
Boa resposta, mas na verdade nunca uso o usuário diretamente no servidor, sempre sshno servidor e, na faixa authorized_keys, o script é chamado e a conexão termina. Como devo modificar authorized_keyspara manter isso funcionando?
Tomáš Blatný 30/03/16
Deve funcionar da mesma maneira. Você estaria autenticando via chave e desde que o shell esteja definido como o script da conta remota em questão no arquivo / etc / passwd do servidor remoto, o script executará. Vou adicionar uma captura de tela ao meu post em breve.
21716 NotAdmin Dave
11
@ Dave não pode esperar para o seu livro
Burgi
Obrigado pela sua resposta, ele não resolveu o meu problema, mas foi para mim o mais interessante e resolveu outros problemas que tive. Deu-lhe a generosidade, obrigado novamente
Tomáš Blatny
4

O envcomando examinará o usuário $PATHpara encontrar o primeiro executável do nome fornecido. Portanto, /usr/bin/env phpprocurará um arquivo executável chamado phpem qualquer um dos diretórios $PATHdo usuário que o está executando.

No seu caso, é quase certo que, ao executar um comando ssh, você não inicia um shell completo e na verdade não lê os arquivos de inicialização do seu shell. Você pode verificar isso executando este comando (observe as aspas simples):

ssh deployer@XXX.com 'echo $PATH'

E comparando a saída com o que você obtém se você ssh [email protected]e depois executar echo $PATH. No meu sistema por exemplo:

$ 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

Portanto, o $PATHacesso ao qual seu script é executado ssh [email protected]não é o mesmo que quando você faz login para testá-lo.

De qualquer forma, a solução simples é usar o caminho completo para o intérprete em vez de env. Os envcaminhos completo e completo têm seus benefícios e desvantagens , mas, nesse caso, o caminho é mais seguro:

#!/usr/bin/php
Terdon
fonte
ITYM " observe as aspas simples" não " não ".
dave_thompson_085
@ dave_thompson_085 de fato eu fiz, obrigado.
terdon
Na verdade, estou usando caminhos completos em todos os lugares, como mencionei na minha pergunta, o erro é relatado dentro do composer install comando, o qual obviamente não posso modificar. Também $PATHestá ok, como mencionei na minha pergunta também, verifiquei todas as coisas adicionando-as ao script e executando remotamente via login ssh. Também não consigo verificar o ssh [email protected] 'echo $PATH'que você declarou, pois meu login ssh é limitado a apenas um script, mas eu nunca o verifiquei quando adicionei $ PATH a esse script (declarado acima). De qualquer forma, obrigado por sua resposta e aceite + 1 por me explicar o envproblema #
Tomáš Blatný 30/03
@ TomášBlatný bem, você está usando env em algum lugar ou não vê esse erro. Eu não sei compositor, mas você provavelmente terá que copiar ou vincular o executável php a um diretório em seu caminho. É difícil depurar esse tipo de coisa, pois existem muitas coisas, uma dependendo da outra.
terdon
Isso é verdade, envé realmente chamado de compositor interno. Mas isso não resolve o problema, por que algumas chamadas do compositor passam e outras não. No entanto, investigarei mais isso analisando seu código. Obrigado pelo seu tempo
Tomáš Blatný
2

É possível que seja bashnecessário redefinir sua tabela de hash?

Nesse caso, tente adicionar hash -ralgum lugar no seu script, o que força o shell a examinar $PATHnovamente em vez de confiar nas informações (possivelmente desatualizadas) da tabela de hash.

Quando necessário, hashtambém pode permitir que o shell lembre de caminhos para executáveis ​​instalados em locais não padrão usando a -popção, ou esqueça os caminhos com a -dopção

Fontes:

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

voador
fonte
Este fez não resolveu o problema para mim, no entanto o seu conhecimento uma boa, então eu adicionei-lhe uma +1
Tomáš Blatny
1

Parece que talvez você precise adicionar php ao seu caminho. Tentar:

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

Você também pode verificar onde está o seu php para ter certeza de que o caminho está correto. Tentar:

which php
Jeramy
fonte
Bem, este não é o problema, uma vez que as php -vsaídas corrigem a versão PHP e a composer --versionversão do compositor. Como eu disse, o problema está em apenas um comando.
Tomáš Blatný
1

É claro que você tem um problema de caminho, pois seu script de implantação não consegue encontrar coisas que estão definitivamente no caminho quando você faz um login ssh normal.

A primeira coisa a fazer para confirmar que você tem um problema PATH é atualizar o script de implantação para registrar a saída envou pelo menos echo $PATH. Eu estou supondo que, como o script de implantação é chamado, $ PATH não está definido como você esperaria. Essa saída de depuração confirmará / negará minha teoria.

Eu olhei para o tutorial que você seguiu. Você provavelmente deve certificar-se de atualização a command=ser command="/bin/sh /path/to/your/script..."se você já não tiver que se certificar que seu script é executado pelo shell direita.

Se você tiver um problema PATH, uma correção rápida / suja é apenas para definir explicitamente PATH no início do script de implementação.

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

Explicação detalhada e outras opções ...

No linux, quando os comandos são executados, eles herdam o ambiente do processo pai.

Quando você faz login como um usuário normal via SSH, acontecem coisas (como executar / etc / bashrc / etc / profile ~ / .bash_profile ~ / .bashrc etc). Nesse ponto, você pode ter atualizado o ambiente do seu processo fazendo coisas como export PATH="$PATH:~/mybin"nesses scripts. Agora, quaisquer processos futuros que você executar herdarão seu ambiente atual.

Executar um comando em vez de obter um shell de login significa que o comando é executado pelo daemon ssh e herdará o ambiente do processo do daemon ssh ... o que provavelmente é diferente do seu ambiente como usuário logado.

A página de manual para chaves autorizadas cobre o que acontece após a autenticação. Em relação ao meio ambiente:

  1. Lê o arquivo ~ / .ssh / environment, se existir, e os usuários podem alterar seu ambiente. Veja a opção PermitUserEnvironment em sshd_config (5).

Portanto, o local apropriado para configurar o ambiente para o processo é ~/.ssh/environmentonde ~está o diretório inicial do usuário autenticado para executar o comando. Você também precisa verificar seu sshd_config para garantir que PermitUserEnvironment seja permitido.

~/.ssh/environment O formato também é especificado na página do manual, é claro.

         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.

Uma maneira alternativa de especificar o ambiente sem usar o método mencionado acima é usar a environment="NAME=value"opção no arquivo allowed_keys. Veja a página de manual que eu vinculei acima para obter detalhes.

mattpr
fonte
Em relação a Without knowing exactly how you have setup your deploy script to run: na minha pergunta no início, há um link, como eu o configurei (usando ~/.ssh/authorized_keys. Obrigado pela dica com o comando de atualização, eu tentei, mas infelizmente sem diferença. No entanto, investigarei mais isso e tentarei conchas diferentes Por favor, aceite um +1 para essa idéia.
Tomáš Blatný
Você tentou atualizar o script de implantação para imprimir o $ PATH atual? Você poderia postar o resultado? Se não corresponder ao que você espera, tente configurar o PATH explicitamente, conforme sugeri no início do script de implantação.
mattpr