Linux /bin/sh: pushd: 未找到

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5193048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:27:31  来源:igfitidea点击:

/bin/sh: pushd: not found

linux

提问by Pein

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 所以我认为这不会导致问题。

回答by sarnold

pushdis a bashenhancement to the POSIX-specified Bourne Shell. pushdcannot be easily implemented as a command, because the current working directory is a feature of a process that cannot be changed by child processes. (A hypothetical pushdcommand mightdo the chdir(2)call and then start a new shell, but ... it wouldn't be very usable.) pushdis a shell builtin, just like cd.

pushdbash对 POSIX 指定的 Bourne Shell的增强。pushd不能简单地作为命令实现,因为当前工作目录是进程的一个特性,子进程不能改变。(假想的pushd命令可能会做的chdir(2)呼叫,然后启动一个新的外壳,但是......它不会是非常有用的。)pushd是一个shell内建命令,就像cd

So, either change your script to start with #!/bin/bashor store the current working directory in a variable, do your work, then change back. 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.

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

回答by hlovdal

This is because pushd is a builtin function in 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)).

这是因为 pushd 是 bash 中的内置函数。因此它与 PATH 变量无关,而且 /bin/sh 也不支持它(make 默认使用它。您可以通过设置 SHELL 来更改它(尽管它不会直接工作(test1))。

You can instead run all the commands through bash -c "...". That will make the commands, including pushd/popd, run in a bash environment (test2).

您可以改为通过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;"

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 中运行。

回答by joseignaciorc

Your shell (/bin/sh) is trying to find 'pushd'. But it can't find it because 'pushd','popd' and other commands like that are build in bash.

您的 shell (/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

使用 Bash (/bin/bash) 而不是像你现在所做的那样启动你的脚本,它会起作用

回答by Jan Hudec

Synthesizing from the other responses: pushdis 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:

从其他响应综合: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

(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. Just

由于您是从 make 运行它,我也可能会用 make 规则替换测试。只是

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.pltoo, so the Makefilein genwill 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.

(删除当前目录前缀;无论如何,您在某些时候使用了相对路径)而不只是使规则依赖于gen/SvcGenLog. 它会更具可读性,您也可以使其依赖于genscript/genmakefile.pl,因此如果您修改脚本,Makefileingen将重新生成。当然,如果其他任何影响 的内容Makefile,您也可以使规则依赖于它。

回答by Mark Baker

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!

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

回答by Juan Jose Pablos

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 语法?

回答by Classified

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 回来。

i.e.

IE

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

回答by MatanN

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

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

回答by user2438597

sudo dpkg-reconfigure dash 

Then select no.

然后选择no

回答by Born2Smile

This ought to do the trick:

这应该可以解决问题:

( cd dirname ; pwd ); pwd

The parentheses start a new child shell, thus the cdchanges the directory within the child only, and any command after it within the parentheses will run in that folder. Once you exit the parentheses you are back in wherever you were before..

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