`pushd .` 和 `cd -` 之间的冲突

`pushd .` 和 `cd -` 之间的冲突

我很高兴使用cd -转到上一个目录的命令。同时我也喜欢pushd .popd

但是,当我想通过 记住当前工作目录时pushd .,我就失去了通过 转到上一个目录的可能性cd -。 (pushd .也执行cd .)。

我怎样才能使用pushd仍然可以使用cd -

顺便说一句:GNU bash,版本 4.1.7(1)

答案1

你可以使用这样的东西:

push() { 
    if [ "$1" = . ]; then
        old=$OLDPWD
        current=$PWD
        builtin pushd .
        cd "$old"
        cd "$current"
    else
        builtin pushd "$1"
    fi
}

如果您将其命名为pushd,那么它将优先于内置函数,因为函数在内置函数之前进行评估。

您需要变量oldcurrent因为覆盖OLDPWD会使其失去其特殊含义。

答案2

稍微简洁一点的版本沃伊泰克的回答:

pushd () {
        if [ "$1" = . ]; then
                cd -
                builtin pushd -
        else    
                builtin pushd "$1"
        fi      
}

通过给函数命名pushd,就可以正常使用pushd,不需要记住使用函数名称。

答案3

凯文的回答非常好。我已经写了一些有关正在发生的事情的详细信息,以防人们希望更好地理解为什么他们的脚本对于解决问题是必要的。

如果我们深入研究 cd 和目录堆栈的工作原理,pushd .破坏 行为的原因就会显而易见。cd -让我们将一些目录压入堆栈:

$ mkdir dir1 dir2 dir3
$ pushd dir1
~/dir1 ~
$ pushd../dir2
~/dir2 ~/dir1 ~
$ pushd../dir3
~/dir3 ~/dir2 ~/dir1 ~
$ dirs -v
0       ~/dir3
1       ~/dir2
2       ~/dir1
3       ~

现在我们可以尝试cd -跳回一个目录:

$ cd -
/home/username/dir2
$ dirs -v
0       ~/dir2
1       ~/dir2
2       ~/dir1
3       ~

我们可以看到,cd -我们跳回了上一个目录,将 stack ~0 替换为我们跳入的目录。我们可以再次跳回来cd -

$ cd -
/home/username/dir3
$ dirs -v
0       ~/dir3
1       ~/dir2
2       ~/dir1
3       ~

请注意,我们跳回到以前的目录,即使以前的目录实际上并未在目录堆栈中列出。这是因为cd使用环境变量$OLDPWD来跟踪前一个目录:

$ echo $OLDPWD
/home/username/dir2 

如果这样做,pushd .我们会将当前目录的额外副本推送到堆栈上:

$ pushd . 
~/dir3 ~/dir3 ~/dir2 ~/dir1 ~
$ dirs -v
0       ~/dir3
1       ~/dir3
2       ~/dir2
3       ~/dir1
4       ~

除了在堆栈中制作当前目录的额外副本之外,pushd .还更新了$OLDPWD

$echo $OLDPWD
/home/username/dir3

因此cd -已经失去了有用的历史记录,现在只会将您移动到当前目录 - 什么也不做。

相关内容