/ usr / bin / env : PHP : 그런 파일이나 디렉토리가 없습니다


9

내 앱 배포에 .sh 스크립트를 사용하고 싶습니다. 이 스크립트는 내 홈 서버 (우분투 15.10 서버)에 있으며 실행 가능으로 표시되어 있습니다. 이 스크립트에 대한 액세스는 ssh를 통해 수행되며, 이 학습서를 사용하여 해당 스크립트를 실행하는 ssh 로그인을 설정했습니다. 기본적으로 방금 호출 하면 매개 변수로 ssh deployer@XXX.com someArguments스크립트를 실행 someArguments합니다. 사용자 deployer는 기본적으로 uid = 0이므로 기본적으로 root변경됩니다 (향후 변경 될 것이므로 제대로 작동 할 때까지 권한 문제를 제거하도록 설정했습니다).

그리고 여기가 까다로운 곳이 있습니다. 스크립트 /usr/bin/env: php: No such file or directory는 명령에 작성합니다 /bin/composer install( Composer 사용 ). 내가 그 스크립트를 더 많이 볼수록 상황이 더 이상해집니다. 이 줄 앞에는 및가 /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.sh루트 와 마찬가지로 스크립트를 직접 실행 (사용자와 동일하므로)-오류없이 완벽하게 작동
  • 실패한 명령을 직접 실행-오류없이 완벽하게 실행

따라서 이것은 매우 구체적인 경우 인 것 같습니다.이 명령이 작동하지 않는 이유는 무엇입니까? 나는 그것을 디버깅하는 데 12 시간을 보냈으며 여기서 아이디어가 없습니다.

추신 : 비슷한 오류 ( /usr/bin/env: node: No such file or directory)가있을 때 bower install( Bower 사용 ) 발생 하지만 실행 되지 않을 때 npm install( NPM 사용 ) 발생합니다.


sh deploy대신 bash deploybashism을 실행하십시오 . " 다음 사항 "을 어떻게 확인 했 습니까? 필자는 스크립트에서이를 확인하여 결국 env의 재정의와 위생을 발견 할 것을 권장합니다.
— Giacomo Catenazzi

" follow things " 에 관해 : deploy.sh 스크립트를 시작하기 위해 그것들을 추가하고 질문에 넣은 것들을 출력합니다. 그러나 동일한 결과는 내가 혼자 실행할 때입니다.
— Tomáš Blatný

sh deploy그리고 bash deploy모두 같은 결과를 얻을 수
— 토마스 Blatný에게

그 줄을 여기에 보여주세요. / usr / bin / env를 호출 할 때 환경 변수를 검사하기 위해 스크립트의이 줄에있는 php 명령을 파일 출력 으로 바꾸는 것이 좋습니다 ./usr/bin/env > environment.txt
— Oleg Bolden

답변:


6

줄 끝 및 / 또는 보이지 않는 공간으로 인해 문제가 발생하지 않는지 확인하십시오.

스크립트의 첫 번째 줄에서 공백을 제거하고 새 공백을 삽입하십시오. 스페이스를 누를 때 CTRL을 잡지 마십시오.

또한 DOS 줄 끝 (CR + LF)이 없는지 확인하십시오. 자세한 내용은 /programming/82726/convert-dos-line-endings-to-linux-line-endings-in-vim 을 참조하십시오.


CR + LF를 자동으로 확인하고 LF로 변환하는 IDE를 사용하고 있습니다 .BOM을 제거하고 흰색 문자를 신경 쓰지만 다시 확인한 후 확인 표시 (아직 작동하지 않음). 어쨌든 감사합니다
— Tomáš 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이 작업을 유지하려면 어떻게 수정해야 합니까?
— Tomáš Blatný

동일하게 작동해야합니다. 키를 통해 인증하고 셸이 원격 서버의 / etc / passwd 파일 내에서 해당 원격 계정의 스크립트로 설정되어 있으면 스크립트가 실행될 것입니다. 곧 게시물에 스크린 샷을 추가하겠습니다.
— NotAdmin Dave

1
@Dave는 당신의 책을 기다릴 수 없습니다
— Burgi

귀하의 답변에 감사드립니다, 그것은 내 문제를 해결하지 못했지만 나에게 가장 흥미롭고 실제로 다른 문제를 해결했습니다. 다시 한번 감사합니다
— Tomáš 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

@ dave_thompson_085 감사합니다.
— terdon

내 질문에서 언급했듯이 실제로 모든 곳에서 전체 경로를 사용하고 있습니다. 오류는 명령 내부 에보고 되어composer install 분명히 수정할 수 없습니다. 또한 $PATH내 질문에서 언급했듯이 스크립트에 추가하고 ssh 로그인을 통해 원격으로 실행하여 모든 것을 확인했습니다. 또한 ssh deployer@XXX.com 'echo $PATH'ssh 로그인이 하나의 스크립트로만 제한되어 있기 때문에 언급 한대로 확인할 수는 없지만 위의 스크립트에 $ PATH를 추가하면 ovever가 확인했습니다. 1 나에게 설명하기위한 env것
— 토마스 Blatný

@ TomášBlatný 글쎄, 당신은 어딘가에서 env를 사용하고 있거나 그 오류가 표시되지 않을 것입니다. 나는 작곡가를 모르지만 PHP 실행 파일을 경로의 디렉토리에 복사하거나 링크해야 할 것입니다. 이런 종류의 일은 서로에 따라 많은 것들이 있기 때문에 디버깅하기가 어렵습니다.
— terdon

사실 env은 실제로 작곡가 내부라고합니다. 그러나 이것은 문제를 해결하지 못하며, 일부 작곡가 호출이 통과하는 이유와 그렇지 않은 이유가 있습니다. 그러나 코드를 조사하여이를 더 자세히 조사 할 것입니다. 시간 내 주셔서 감사합니다
— Tomáš Blatný

2

그것은 가능성이 bash해시 테이블에 리셋이 필요합니다?

그렇다면 hash -r스크립트 어딘가에 추가를 시도하면 $PATH해시 테이블의 정보에 의존하지 않고 셸을 다시 살펴볼 수 있습니다.

필요한 경우, hash쉘이 -p옵션을 사용하여 비표준 위치에 설치된 실행 파일의 경로를 기억 하거나 옵션으로 경로를 잊을 수 -d있습니다.

출처 :

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


이렇게해도 문제가 해결되지는 않았지만 좋은 지식을
— 얻었으므로

1

경로에 PHP를 추가해야 할 것 같습니다. 시험:

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

PHP가 어디에 있는지 확인하여 경로가 올바른지 확인할 수도 있습니다. 시험:

which php

php -v올바른 PHP 버전을 composer --version출력하고 composer 버전을 출력하기 때문에 이것은 문제가되지 않습니다 . 내가 말했듯이 문제는 하나의 명령에만 있습니다.
— Tomáš 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"

자세한 설명 및 추가 옵션 ...

리눅스에서는 명령이 실행될 때 부모 프로세스의 환경을 상속받습니다.

SSH를 통해 일반 사용자로 로그인하면 / etc / bashrc / etc / profile ~ / .bash_profile ~ / .bashrc 실행과 같은 상황이 발생합니다. 이때 export PATH="$PATH:~/mybin"해당 스크립트 와 같은 작업을 수행하여 프로세스 환경을 업데이트했을 수 있습니다 . 이제 미래에 실행되는 프로세스는 현재 환경을 상속합니다.

로그인 쉘 대신 명령을 실행한다는 것은 ssh 데몬이 명령을 실행하고 ssh 데몬 프로세스의 환경을 상속한다는 것을 의미합니다. 로그인 한 사용자와 환경이 다를 수 있습니다.

인증 된 키의 매뉴얼 페이지는 인증 후 발생하는 사항을 다룹니다. 환경에 관하여 :

  1. ~ / .ssh / environment 파일 (있는 경우)을 읽고 사용자는 환경을 변경할 수 있습니다. sshd_config (5)의 PermitUserEnvironment 옵션을 참조하십시오.

프로세스에 대한 구성 환경에 적절한 장소 그래서 인 ~/.ssh/environment경우 ~명령을 실행하는 인증 된 사용자의 홈 디렉토리입니다. 또한 PermitUserEnvironment가 허용되는지 sshd_config를 점검해야합니다.

~/.ssh/environment 형식은 물론 맨 페이지에도 지정되어 있습니다.

         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 파일 의 옵션 을 사용하는 것입니다. 자세한 내용은 위에 링크 된 매뉴얼 페이지를 참조하십시오.


관련 Without knowing exactly how you have setup your deploy script to run: 처음에 내 질문에는 링크를 설정하는 방법이 있습니다 (을 사용 ~/.ssh/authorized_keys합니다. 업데이트 명령으로 팁에 감사드립니다. 그 아이디어에 +1을 수락하십시오
— Tomáš Blatný

현재 $ PATH를 인쇄하기 위해 배포 스크립트를 업데이트하려고 했습니까? 결과를 게시 할 수 있습니까? 예상 한 것과 일치하지 않으면 배포 스크립트 시작 부분에서 제안한대로 PATH를 명시 적으로 설정하면됩니다.
— mattpr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.