/ bin / sh : pushd : 찾을 수 없음


99

make 파일 내에서 다음을 수행하고 있습니다.

pushd %dir_name%

그리고 다음과 같은 오류가 발생합니다.

/bin/sh : pushd : not found

누군가이 오류가 나타나는 이유를 알려주시겠습니까? 내 $ PATH 변수를 확인했는데 / bin이 포함되어 있으므로 문제가 발생하지 않는다고 생각합니다.


sh에 대해 불평하는 것이 아니라 찾을 수 없다고 불평합니다 pushd. 당신의 밀어 $PATH?
Konerak 2011 년

7
Konerak : pushd는 경로에있는 것이 의미가 없습니다. bash 내장입니다. 문제 는 POSIX 쉘이 아닌 bash 내장입니다.
Jan Hudec 2011 년

코드를 편집 한 이유는 무엇입니까?
Jan Hudec 2011 년

1
배포판이 / bin / sh를 / bin / bash가 아닌 / bin / ash로 옮겼을 가능성이 높습니다. Make가 bash를 사용하도록 특별히 강요하지 않는 한 / bin / sh가 무엇이든 사용합니다.
stsquad

bash가 아닌 경우 쉘 스크립트에서도 동일한 문제가 발생합니다.
Vladimir Kroz 2015 년

답변:


113

pushdbashPOSIX 지정 Bourne Shell에 대한 개선 사항입니다. pushd현재 작업 디렉토리는 자식 프로세스에서 변경할 수없는 프로세스의 기능이기 때문에 명령으로 쉽게 구현할 수 없습니다. (A 가상 pushd명령이 할 일 chdir(2)이 매우 사용할 수없는 것입니다 ... 전화를 한 다음 새 쉘을 시작하지만,하는.) pushd처럼, 쉘 내장입니다 cd.

따라서 스크립트를 시작하도록 변경 #!/bin/bash하거나 현재 작업 디렉토리를 변수에 저장하고 작업을 수행 한 다음 다시 변경하십시오. 매우 축소 된 시스템 (예 : Debian 빌드 서버)에서 작동하는 쉘 스크립트를 원하는지 또는 항상 bash.


17
OP는 make에서 실행되었다고 말합니다. 따라서 SHELL = /bin/bash스크립트를 시작하는 대신 #!/bin/bash.
Jan Hudec 2011 년

@Jan Hudec, 아! 잘 잡았습니다. 감사.
sarnold 2011 년

그러나이 경우 SHELL 설정은 작동하지 않습니다 . test1내 대답 stackoverflow.com/questions/5193048/bin-sh-pushd-not-found/…를 참조하십시오 .
hlovdal 2011 년

1
@hlovdal : 아니요, 실제로 충분하지 않습니다.
Jan Hudec 2011 년

1
#!/bin/bash파일의 첫 번째 줄 인지 확인하십시오 .
Michael Cole


18

이에 대한 해결 방법은 변수가 현재 작업 디렉토리를 가져 오도록하는 것입니다. 그런 다음 CD에서 꺼내서 무엇이든 할 수 있으며 필요할 때 다시 CD로 들어갈 수 있습니다.

oldpath =`pwd`
# 스크립트가하는 일을
...
...
...
# 당신이 밀고 자했던 디렉토리로 돌아갑니다.
cd $ oldpath

6
cd원하는 디렉토리로 이동할 수도 있으며 나중에 inbetween을 사용하지 않을 경우 cd -해당 $oldpath변수 를 사용할 필요 가 없습니다 cd. 흥미로운 점은 pushd사용할 때마다 디렉토리를 스택으로 푸시하고 나중에를 사용하여 최신 디렉토리로 돌아갈 수 popd있으므로 둘 이상의 디렉토리로 이동하여 원하는 경우 사용하는 것이 합리적이라는 것입니다. 확실한 방법입니다.
Enrico

1
그것은 단지 oneliner을의 경우, 다음과 수도도 작업(cd /new_path ; command )
barney765

10

이는 pushd가 bash의 내장 함수이기 때문입니다. 따라서 PATH 변수와 관련이 없으며 / bin / sh에서 지원하지 않습니다 (기본적으로 make에서 사용합니다. SHELL을 설정하여 변경할 수 있지만 (test1) 직접 작동하지는 않음).

대신를 통해 모든 명령을 실행할 수 있습니다 bash -c "...". 그러면 pushd / popd를 포함한 명령이 bash 환경 (test2)에서 실행됩니다.

SHELL = /bin/bash

test1:
        @echo before
        @pwd
        @pushd /tmp
        @echo in /tmp
        @pwd
        @popd
        @echo after
        @pwd

test2:
        @/bin/bash -c "echo before;\
        pwd; \
        pushd /tmp; \
        echo in /tmp; \
        pwd; \
        popd; \
        echo after; \
        pwd;"

make test1 및 make test2를 실행하면 다음이 제공됩니다.

prompt>make test1
before
/download/2011/03_mar
make: pushd: Command not found
make: *** [test1] Error 127
prompt>make test2
before
/download/2011/03_mar
/tmp /download/2011/03_mar
in /tmp
/tmp
/download/2011/03_mar
after
/download/2011/03_mar
prompt>

test1의 경우 bash가 셸로 사용 되더라도 규칙의 각 명령 / 줄은 자체적으로 실행되므로 pushd 명령은 popd와 다른 셸에서 실행됩니다.


1
@Jan Hudec, 내가 생각하는 tcsh(아마도 csh?) 자신의 메시지와 함께 종료 않습니다 > :$ tcsh haig:/> exit $ csh haig:/> exit $
sarnold

내 것이 :) 사실 내 PS1은 (\u) \h:\w>있지만 대답을 위해 이제 일반 문자열로 제거했습니다. DOS의 프롬프트는 >기본적으로 $P$GIIRC ( IIRC)로 끝납니다 .
hlovdal 2011 년

설정 SHELL와 : =하지 =

"SHELL = / bin / bash"설정은 저에게 잘 작동하지만 어떻게 작동하지 않는지 확실하지 않습니다.
Isaac Freeman

4

쉘 (/ bin / sh)이 'pushd'를 찾으려고합니다. 그러나 'pushd', 'popd'및 기타 명령이 bash에서 빌드 되었기 때문에 찾을 수 없습니다.

지금하는 것처럼 Sh 대신 Bash (/ bin / bash)를 사용하여 스크립트를 시작하면 작동합니다.



2

다른 응답에서 합성 : pushdbash에 따라 다르며 다른 POSIX 쉘을 사용하고 있습니다. 다른 디렉토리가 필요한 부분에 대해 별도의 쉘을 사용하는 간단한 해결 방법이 있으므로 다음으로 변경하십시오.

test -z gen || mkdir -p gen \
 && ( cd $(CURRENT_DIRECTORY)/genscript > /dev/null \
 && perl genmakefile.pl \
 && mv Makefile ../gen/ ) \
 && echo "" > $(CURRENT_DIRECTORY)/gen/SvcGenLog

(긴 경로를 변수 확장으로 대체했습니다. 아마도 메이크 파일에서 하나이고 현재 디렉토리로 명확하게 확장됩니다).

make에서 실행하고 있으므로 테스트를 make 규칙으로 대체 할 수도 있습니다. 다만

gen/SvcGenLog :
    mkdir -p gen
    cd genscript > /dev/null \
     && perl genmakefile.pl \
     && mv Makefile ../gen/ \
    echo "" > gen/SvcGenLog

(현재 디렉토리 접두사를 삭제했습니다. 어쨌든 일부 지점에서 상대 경로를 사용했습니다) 그리고 규칙이 gen/SvcGenLog. 좀 더 읽기 쉽고에 의존하도록 만들 수 genscript/genmakefile.pl있으므로 스크립트를 수정하면 Makefilein gen이 다시 생성됩니다. 물론 다른 것이의 내용에 영향을 미치는 경우 Makefile규칙도 이에 따라 달라 지도록 할 수 있습니다.


2

make 파일에 의해 실행되는 각 행은 어쨌든 자체 쉘에서 실행됩니다. 디렉토리를 변경해도 후속 행에는 영향을주지 않습니다. 그래서 당신은 아마도 pushd와 popd를 거의 사용하지 않을 것입니다. 당신의 문제는 당신이 필요로하는 한 디렉토리를 계속 변경하는 것과는 정반대입니다!


1

"apt install bash"를 실행하면 필요한 모든 것이 설치되고 명령이 작동합니다.


1

여기에 지적하는 방법이 있습니다

sh-> bash

터미널에서이 명령을 실행

sudo dpkg-reconfigure dash

이 후에 당신은 볼 것입니다

ls -l /bin/sh

/ bin / bash를 가리키고 (/ bin / dash가 아니라)

참고


0

이것은 트릭을 수행해야합니다.

( cd dirname ; pwd ); pwd

괄호는 새 자식 셸을 시작하므로 cd자식 내의 디렉터리 만 변경되며 괄호 안의 모든 명령은 해당 폴더에서 실행됩니다. 괄호를 종료하면 이전에 있던 곳으로 돌아갑니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.