/ 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.