/ usr / bin / env:php:そのようなファイルやディレクトリはありません


9

アプリのデプロイに.shスクリプトを使用したい。このスクリプトは私のホームサーバー(Ubuntu 15.10サーバー)にあり、実行可能としてマークされています。このスクリプトへのアクセスはsshを介して行われ、このチュートリアルを使用して、そのスクリプトを実行するsshログインを設定しました。したがって、基本的には呼び出すだけでssh deployer@XXX.com someArguments、スクリプトをsomeArgumentsパラメーターとして実行します。ユーザーdeployerはuid = 0を持っているので、基本的にはroot(これは将来変更される予定です。正常に機能するまで、アクセス許可の問題を解消するためだけに設定しました)。

そして、ここが物事がトリッキーになるところです。スクリプトは/usr/bin/env: php: No such file or directoryatコマンドを報告します/bin/composer installComposerを使用)。私がそのスクリプトを見るほど、物事は奇妙です。この行の前に、/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.shrootの下で直接スクリプトを実行する(そのユーザーと同じであるため)-エラーなしで完全に動作します
  • 失敗したコマンドを直接実行する-エラーなしで完全に実行する

したがって、これは非常に特殊なケースとして私には思われますが、このコマンドが機能しないのはなぜですか。デバッグに12時間費やしましたが、ここでは考えきれません。

PS:同様のエラー(/usr/bin/env: node: No such file or directory)が存在する場合bower installBowerを使用)に発生しますが、実行中(NPMを使用)には発生しませんnpm install


(たぶんいくつかのバシズム)のsh deploy代わりに実行しますbash deploy。「次のこと」をどのように確認しましたか?スクリプトでそれらをチェックすることをお勧めします。これにより、envの最終的なオーバーライドとサニテーションを見つけることができます。
Giacomo Catenazzi 16年

次のこと」に関して:それらをdeploy.shスクリプトの最初に追加し、質問にこれらのことを出力しました。ただし、これらを単独で実行した場合も同じ出力になります。
トマーシュBlatný

sh deployそしてbash deployどちらも同じ結果が得られます
トマーシュBlatný

ここにその行を示してください。私はあなたの交換することをお勧めしますPHPの呼び出しは/ usr / binに/ ENVの瞬間に、環境変数を調べるために、ファイルに出力してスクリプトにこの行でコマンドを:/usr/bin/env > environment.txt
オレグボールデン

回答:


6

行末や非表示のスペースが問題の原因となっていないことを確認してください。

スクリプトの最初の行のスペースを削除し、新しいスペースを挿入します。スペースを押すときにCTRLキーを押したままにしないでください。

また、DOSの行末(CR + LF)がないことを確認してください。詳細については、https://stackoverflow.com/questions/82726/convert-dos-line-endings-to-linux-line-endings-in-vimを参照してください。


私はIDEを使用しています。これはCR + LFを自動的にチェック(および変換)し、BOMを削除し、白い文字を気にしますが、ダブルチェックしましたが、問題はありません(まだ機能しません)。とにかく感謝
トマーシュ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

サンプル いつでも動作します!スクリプトを使用して、設定されていないと思われる環境変数のトラブルシューティングやデバッグを行うこともできます。また、sshに渡される引数の処理も機能します。

注:スクリプト、実行可能ファイルなどのパスを常に完全に修飾することをお勧めします。上記は、デフォルトのパスを設定して、mooフォルダー内のmoo.shを呼び出すことを許可する例です;)

それは簡単でした..投稿していただきありがとうございます..

リファレンス:/ etc / passwd形式


いい答えですが、実際にはサーバー上のユーザーを直接使用することはなく、常にsshサーバーにアクセスします。レーンでauthorized_keysは、スクリプトが呼び出され、接続が終了します。authorized_keysこれを機能させるには、どのように変更すればよいですか?
トマーシュBlatný

同じように動作するはずです。キーを使用して認証し、シェルがリモートサーバーの/ etc / passwdファイル内の問題のリモートアカウントのスクリプトに設定されている限り、スクリプトが実行されます。まもなくスクリーンショットを投稿に追加します。
NotAdmin Dave 2016

1
@デーブはあなたの本を待つことができません
ブルギ

あなたの答えをありがとう、それは私の問題を解決しませんでしたが、私にとって私にとって最も興味深く、実際に解決した他の問題でした。あなたの恵み、感謝再び与えた
トマーシュBlatný

4

この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 2016年

@ dave_thompson_085本当にありがとうございます。
terdon 2016年

私は実際にどこでもフルパスを使用していますが、私の質問で述べたように、エラーはコマンド で報告さますがcomposer install、明らかに変更できません。また$PATH、質問でも述べたように、すべてのものをスクリプトに追加し、sshログインを介してリモートで実行することで、すべてをチェックしました。またssh deployer@XXX.com 'echo $PATH'、私のsshログインは1つのスクリプトのみに制限されているため、あなたが述べたようにを確認することはできませんが、そのスクリプトに$ PATHを追加するときに確認しました(上記のとおり)とにかく、あなたの答えに感謝し、+ 1私に説明するためのenvもの
トマーシュBlatný

@TomášBlatnýええと、envをどこかで使用していると、そのエラーは表示されません。作曲家はわかりませんが、php実行可能ファイルをそのパスのディレクトリにコピーまたはリンクする必要があります。この種のものは、互いに依存し合うものが非常に多いため、デバッグが困難です。
terdon 2016年

それenvは本当です、実際に作曲家の中で呼ばれます。しかし、これは問題を解決しません。なぜ、いくつかのcomposer呼び出しが成功するのか、そうでないのかです。ただし、そのコードを調べて、さらに調査します。お時間をありがとう
トマーシュBlatný

2

bashハッシュテーブルをリセットする必要がある可能性はありますか?

その場合hash -rは、スクリプトのどこかに追加してみて$PATHください。これにより、ハッシュテーブルの(古くなっている可能性がある)情報に頼るのではなく、シェルがもう一度調査するようになります。

必要に応じhashて、-pオプションを使用して標準以外の場所にインストールされた実行可能ファイルへのパスをシェルが記憶できるようにしたり、オプションでパスを忘れたりすることも-dできます。

出典:

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


私はあなたに1を追加しましたので、これは、私のためしかし、その優れた知識を、問題を解決していなかった
トマーシュBlatný

1

パスにphpを追加する必要があるようです。試してください:

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

また、phpがどこにあるかをチェックして、パスが正しいことを確認することもできます。試してください:

which php

まあ、これは問題ではありません。php -v正しいPHPバージョンをcomposer --version出力し、composerバージョンを出力するためです。言ったように、問題は1つのコマンドだけです。
トマーシュBlatný

1

通常のsshログインを実行すると、デプロイスクリプトがパス上にあるものを確実に見つけられないため、パスの問題があることは明らかです。

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デーモンプロセスの環境を継承します。これは、ログインユーザーとしての環境とは異なる可能性があります。

承認されたキーのmanページは、認証後に何が起こるかをカバーしています。環境について:

  1. ファイル〜/ .ssh / environmentが存在する場合はそれを読み取り、ユーザーは環境を変更できます。sshd_config(5)のPermitUserEnvironmentオプションを参照してください。

プロセスのためのconfigure環境への適切な場所そこらである~/.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ファイルのオプションを使用することです。詳細については、上記でリンクしたmanページを参照してください。


についてWithout knowing exactly how you have setup your deploy script to run:最初の質問には、リンク、設定方法があります(を使用してい~/.ssh/authorized_keysます。更新コマンドのヒントをありがとう、試してみましたが、違いはありませんでした。ただし、これをさらに調査し、別のシェルを試します。そのアイデアのための1を受け入れてください。
トマーシュBlatný

現在の$ PATHを出力するように展開スクリプトを更新してみましたか?結果を投稿してもらえますか?予想と一致しない場合は、デプロイスクリプトの冒頭で提案したように、PATHを明示的に設定してみてください。
mattpr 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.