简体   繁体   English

/bin/sh: pushd: 未找到

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

I am doing the following inside a make file我在 make 文件中执行以下操作

pushd %dir_name%

and i get the following error我收到以下错误

/bin/sh : pushd : not found

Can someone please tell me why this error is showing up ?有人能告诉我为什么会出现这个错误吗? I checked my $PATH variable and it contains /bin so I don't think that is causing a problem.我检查了我的 $PATH 变量,它包含 /bin 所以我认为这不会导致问题。

pushd is a bash enhancement to the POSIX-specified Bourne Shell. pushd是对 POSIX 指定的 Bourne Shell 的bash增强。 pushd cannot be easily implemented as a command, because the current working directory is a feature of a process that cannot be changed by child processes. pushd不能轻易实现为命令,因为当前工作目录是进程的一个特性,子进程无法更改。 (A hypothetical pushd command might do the chdir(2) call and then start a new shell, but ... it wouldn't be very usable.) pushd is a shell builtin, just like cd . (假设的pushd命令可能会执行chdir(2)调用,然后启动一个新的 shell,但是……它不会很有用。) pushd是一个 shell 内置命令,就像cd一样。

So, either change your script to start with #!/bin/bash or store the current working directory in a variable, do your work, then change back.因此,要么将脚本更改为以#!/bin/bash开头,要么将当前工作目录存储在一个变量中,完成您的工作,然后再改回来。 Depends if you want a shell script that works on very reduced systems (say, a Debian build server) or if you're fine always requiring bash .取决于您是否想要一个可在非常精简的系统(例如 Debian 构建服务器)上运行的 shell 脚本,或者您是否总是需要bash

add添加

SHELL := /bin/bash外壳 := /bin/bash

at the top of your makefile I have found it on another question How can I use Bash syntax in Makefile targets?在 makefile 的顶部,我在另一个问题中找到了它如何在 Makefile 目标中使用 Bash 语法?

A workaround for this would be to have a variable get the current working directory.对此的解决方法是让变量获取当前工作目录。 Then you can cd out of it to do whatever, then when you need it, you can cd back in.然后你可以 cd 出来做任何事情,然后当你需要它时,你可以 cd 回来。

ie IE

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

This is because pushd is a builtin function in bash.这是因为 pushd 是 bash 中的内置函数。 So it is not related to the PATH variable and also it is not supported by /bin/sh (which is used by default by make. You can change that by setting SHELL (although it will not work directly (test1)).因此它与 PATH 变量无关,而且 /bin/sh 也不支持它(make 默认使用它。您可以通过设置 SHELL 来更改它(尽管它不会直接工作(test1))。

You can instead run all the commands through bash -c "..." .您可以改为通过bash -c "..."运行所有命令。 That will make the commands, including pushd/popd, run in a bash environment (test2).这将使包括 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;"

When running make test1 and make test2 it gives the following:运行 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>

For test1, even though bash is used as a shell, each command/line in the rule is run by itself, so the pushd command is run in a different shell than the popd.对于 test1,即使 bash 用作 shell,规则中的每个命令/行都是单独运行的,因此 pushd 命令在与 popd 不同的 shell 中运行。

sudo dpkg-reconfigure dash 

然后选择no

Your shell (/bin/sh) is trying to find 'pushd'.您的外壳 (/bin/sh) 正在尝试查找“pushd”。 But it can't find it because 'pushd','popd' and other commands like that are build in bash.但它找不到它,因为 'pushd'、'popd' 和其他类似的命令是在 bash 中构建的。

Launch you script using Bash (/bin/bash) instead of Sh like you are doing now, and it will work使用 Bash (/bin/bash) 而不是像你现在所做的那样启动你的脚本,它会起作用

here is a method to point这是一个指向的方法

sh -> bash sh -> bash

run this command on terminal在终端上运行此命令

sudo dpkg-reconfigure dash

After this you should see在这之后你应该看到

ls -l /bin/sh

point to /bin/bash (and not to /bin/dash)指向/bin/bash(而不是/bin/dash)

Reference 参考

Synthesizing from the other responses: pushd is bash-specific and you are make is using another POSIX shell.从其他响应综合: pushd是特定于 bash 的,而您正在使用另一个 POSIX shell。 There is a simple workaround to use separate shell for the part that needs different directory, so just try changing it to:有一个简单的解决方法可以为需要不同目录的部分使用单独的 shell,因此只需尝试将其更改为:

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). (我用变量扩展替换了长路径。我可能是 makefile 中的一个,它清楚地扩展到当前目录)。

Since you are running it from make, I would probably replace the test with a make rule, too.由于您是从 make 运行它,我也可能会用 make 规则替换测试。 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 . (删除当前目录前缀;无论如何,您在某些时候使用了相对路径)而且不仅仅是使规则依赖于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.它会更具可读性,您也可以使其依赖于genscript/genmakefile.pl ,因此如果您修改脚本, genMakefile将重新生成。 Of course if anything else affects the content of the Makefile , you can make the rule depend on that too.当然,如果其他任何影响Makefile的内容,您也可以使规则依赖于它。

This ought to do the trick:这应该可以解决问题:

( cd dirname ; pwd ); pwd

The parentheses start a new child shell, thus the cd changes the directory within the child only, and any command after it within the parentheses will run in that folder.括号启动一个新的子 shell,因此cd更改子目录中的目录,括号内的任何命令都将在该文件夹中运行。 Once you exit the parentheses you are back in wherever you were before..退出括号后,您将回到之前所在的位置。

Note that each line executed by a make file is run in its own shell anyway.请注意,make 文件执行的每一行无论如何都在其自己的 shell 中运行。 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!所以你可能很少使用 pushd 和 popd,你的问题恰恰相反,只要你需要,让目录保持改变!

运行“apt install bash”它会安装你需要的一切,命令将起作用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM