[英]/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
。
对此的解决方法是让变量获取当前工作目录。 然后你可以 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
,因此如果您修改脚本, gen
的Makefile
将重新生成。 当然,如果其他任何影响Makefile
的内容,您也可以使规则依赖于它。
这应该可以解决问题:
( cd dirname ; pwd ); pwd
括号启动一个新的子 shell,因此cd
更改子目录中的目录,括号内的任何命令都将在该文件夹中运行。 退出括号后,您将回到之前所在的位置。
请注意,make 文件执行的每一行无论如何都在其自己的 shell 中运行。 如果您更改目录,则不会影响后续行。 所以你可能很少使用 pushd 和 popd,你的问题恰恰相反,只要你需要,让目录保持改变!
运行“apt install bash”它会安装你需要的一切,命令将起作用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.