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
/bin/sh: pushd: not found
提问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
pushd
is a bash
enhancement to the POSIX-specified Bourne Shell. 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. (A hypothetical pushd
command mightdo 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
是bash
对 POSIX 指定的 Bourne Shell的增强。pushd
不能简单地作为命令实现,因为当前工作目录是进程的一个特性,子进程不能改变。(假想的pushd
命令可能会做的chdir(2)
呼叫,然后启动一个新的外壳,但是......它不会是非常有用的。)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. 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: 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:
从其他响应综合: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.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.
(删除当前目录前缀;无论如何,您在某些时候使用了相对路径)而不只是使规则依赖于gen/SvcGenLog
. 它会更具可读性,您也可以使其依赖于genscript/genmakefile.pl
,因此如果您修改脚本,Makefile
ingen
将重新生成。当然,如果其他任何影响 的内容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 cd
changes 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
只更改子目录中的目录,括号内的任何命令都将在该文件夹中运行。退出括号后,您将回到之前所在的位置。