簡體   English   中英

/bin/sh: pushd: 未找到

[英]/bin/sh: pushd: not found

我在 make 文件中執行以下操作

pushd %dir_name%

我收到以下錯誤

/bin/sh : pushd : not found

有人能告訴我為什么會出現這個錯誤嗎? 我檢查了我的 $PATH 變量,它包含 /bin 所以我認為這不會導致問題。

pushd是對 POSIX 指定的 Bourne Shell 的bash增強。 pushd不能輕易實現為命令,因為當前工作目錄是進程的一個特性,子進程無法更改。 (假設的pushd命令可能會執行chdir(2)調用,然后啟動一個新的 shell,但是……它不會很有用。) pushd是一個 shell 內置命令,就像cd一樣。

因此,要么將腳本更改為以#!/bin/bash開頭,要么將當前工作目錄存儲在一個變量中,完成您的工作,然后再改回來。 取決於您是否想要一個可在非常精簡的系統(例如 Debian 構建服務器)上運行的 shell 腳本,或者您是否總是需要bash

添加

外殼 := /bin/bash

在 makefile 的頂部,我在另一個問題中找到了它如何在 Makefile 目標中使用 Bash 語法?

對此的解決方法是讓變量獲取當前工作目錄。 然后你可以 cd 出來做任何事情,然后當你需要它時,你可以 cd 回來。

IE

oldpath=`pwd`
#do whatever your script does
...
...
...
# go back to the dir you wanted to pushd
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 用作 shell,規則中的每個命令/行都是單獨運行的,因此 pushd 命令在與 popd 不同的 shell 中運行。

sudo dpkg-reconfigure dash 

然后選擇no

您的外殼 (/bin/sh) 正在嘗試查找“pushd”。 但它找不到它,因為 'pushd'、'popd' 和其他類似的命令是在 bash 中構建的。

使用 Bash (/bin/bash) 而不是像你現在所做的那樣啟動你的腳本,它會起作用

這是一個指向的方法

sh -> bash

在終端上運行此命令

sudo dpkg-reconfigure dash

在這之后你應該看到

ls -l /bin/sh

指向/bin/bash(而不是/bin/dash)

參考

從其他響應綜合: pushd是特定於 bash 的,而您正在使用另一個 POSIX shell。 有一個簡單的解決方法可以為需要不同目錄的部分使用單獨的 shell,因此只需嘗試將其更改為:

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

(我用變量擴展替換了長路徑。我可能是 makefile 中的一個,它清楚地擴展到當前目錄)。

由於您是從 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 ,因此如果您修改腳本, genMakefile將重新生成。 當然,如果其他任何影響Makefile的內容,您也可以使規則依賴於它。

這應該可以解決問題:

( cd dirname ; pwd ); pwd

括號啟動一個新的子 shell,因此cd更改子目錄中的目錄,括號內的任何命令都將在該文件夾中運行。 退出括號后,您將回到之前所在的位置。

請注意,make 文件執行的每一行無論如何都在其自己的 shell 中運行。 如果您更改目錄,則不會影響后續行。 所以你可能很少使用 pushd 和 popd,你的問題恰恰相反,只要你需要,讓目錄保持改變!

運行“apt install bash”它會安裝你需要的一切,命令將起作用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM