/ bin / sh:pushd:找不到

时间:2011-03-04 11:20:16

标签: linux

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

pushd %dir_name%

我收到以下错误

/bin/sh : pushd : not found

有人可以告诉我为什么会出现这个错误吗? 我检查了我的$ PATH变量并且它包含/ bin所以我认为这不会导致问题。

11 个答案:

答案 0 :(得分:95)

pushd是对POSIX指定的Bourne Shell的bash增强功能。 pushd无法轻松实现为命令,因为当前工作目录是子进程无法更改的进程的功能。 (假设的pushd命令可能会执行chdir(2)调用,然后启动一个新的shell,但是......它不会非常有用。)pushd是内置的shell,就像cd一样。

因此,要么将脚本更改为以#!/bin/bash开头,要么将当前工作目录存储在变量中,执行您的工作,然后再进行更改。取决于你是否想要一个可以在非常简化的系统上运行的shell脚本(例如,Debian构建服务器),或者你总是需要bash

答案 1 :(得分:23)

添加

  

SHELL:= / bin / bash

位于makefile的顶部 我在另一个问题How can I use Bash syntax in Makefile targets?

上找到了它

答案 2 :(得分:15)

解决方法是让变量获取当前工作目录。然后你可以用它来做任何事情,然后当你需要它时,你可以回来。

oldpath=`pwd`
#do whatever your script does
...
...
...
# go back to the dir you wanted to pushd
cd $oldpath

答案 3 :(得分: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并生成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中运行。

答案 4 :(得分:2)

你的shell(/ bin / sh)正试图找到'pushd'。但它找不到它,因为'pushd','popd'和其他类似的命令都是用bash构建的。

使用Bash(/ bin / bash)启动脚本,而不是像现在这样使用Sh,它会起作用

答案 5 :(得分:2)

从其他响应中综合: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,因此如果修改脚本,Makefile中的gen将会重新生成。当然,如果有任何其他因素影响Makefile的内容,您也可以使规则依赖于此。

答案 6 :(得分:2)

请注意,make文件执行的每一行无论如何都要在自己的shell中运行。如果更改目录,则不会影响后续行。所以你可能对pushd和popd几乎没什么用,你的问题恰恰相反,只要你需要就让目录保持不变!

答案 7 :(得分:1)

sudo dpkg-reconfigure dash 

然后选择no

答案 8 :(得分:1)

这是一种指向

的方法

sh-> bash

在终端上运行此命令

sudo dpkg-reconfigure dash

在此之后您应该看到

ls -l /bin/sh

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

Reference

答案 9 :(得分:0)

运行“ apt install bash” 它将安装您需要的所有内容,并且该命令将起作用

答案 10 :(得分:0)

这应该可以解决问题:

( cd dirname ; pwd ); pwd

括号会启动一个新的子shell,因此cd仅会更改子目录,并且括号后的任何命令都将在该文件夹中运行。退出括号后,您将回到之前的位置。