developer tip

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

optionbox 2020. 9. 14. 08:19
반응형

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


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

pushd %dir_name%

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

/bin/sh : pushd : not found

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


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

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


더하다

쉘 : = / bin / bash

Makefile의 맨 위에 다른 질문에서 찾았습니다. Makefile 대상에서 Bash 구문을 어떻게 사용할 수 있습니까?


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

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

이는 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와 다른 셸에서 실행됩니다.


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

Launch you script using Bash (/bin/bash) instead of Sh like you are doing now, and it will work


Synthesizing from the other responses: pushd is bash-specific and you are make is using another POSIX shell. There is a simple workaround to use separate shell for the part that needs different directory, so just try changing it to:

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

(I substituted the long path with a variable expansion. I probably is one in the makefile and it clearly expands to the current directory).

Since you are running it from make, I would probably replace the test with a make rule, too. Just

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

(dropped the current directory prefix; you were using relative path at some points anyway) And than just make the rule depend on gen/SvcGenLog. It would be a bit more readable and you can make it depend on the genscript/genmakefile.pl too, so the Makefile in gen will be regenerated if you modify the script. Of course if anything else affects the content of the Makefile, you can make the rule depend on that too.


Note that each line executed by a make file is run in its own shell anyway. If you change directory, it won't affect subsequent lines. So you probably have little use for pushd and popd, your problem is more the opposite, that of getting the directory to stay changed for as long as you need it!


Run "apt install bash" It will install everything you need and the command will work

참고URL : https://stackoverflow.com/questions/5193048/bin-sh-pushd-not-found

반응형