/bin/sh:pushd:未找到

问题描述 投票:0回答:11

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

pushd %dir_name%

我收到以下错误

/bin/sh : pushd : not found

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

linux
11个回答
155
投票

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

因此,要么将脚本更改为以

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


41
投票

添加

外壳:= /bin/bash

在 makefile 的顶部 我在另一个问题上找到了它如何在 Makefile 目标中使用 Bash 语法?


24
投票

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

旧路径=`密码`
#做你的脚本所做的一切
...
...
...
# 返回到你想要推送的目录
cd $旧路径

13
投票
sudo dpkg-reconfigure dash 

然后选择

no


13
投票

这是因为

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


11
投票

这应该可以解决问题:

( cd dirname ; pwd ); pwd

括号启动一个新的子 shell,因此

cd
仅更改子 shell 中的目录,括号内后面的任何命令都将在该文件夹中运行。一旦退出括号,您就会回到之前的位置..


7
投票

您的 shell (/bin/sh) 正在尝试查找“pushd”。但它找不到它,因为 'pushd'、'popd' 和其他类似命令是在 bash 中构建的。

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


7
投票

这里有一个指向方法

sh -> bash

在终端上运行此命令

sudo dpkg-reconfigure dash

之后你应该会看到

ls -l /bin/sh

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

参考


3
投票

从其他响应综合:

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
的内容,您也可以使规则依赖于此。


3
投票

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


2
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.