使用 pushd 和 popd 导航 Bash Shell

Pushd 和 popd 是你从未听说过的最快的导航命令。
348 位读者喜欢这个。
bash logo on green background

Opensource.com

pushdpopd 命令是 Bash shell 的内置功能,可帮助你“标记”目录,以便在硬盘驱动器上的位置之间快速导航。你可能已经觉得终端是导航计算机的一种快得不可思议的方式;只需按几下键,你就可以去硬盘驱动器、连接的存储设备或网络共享上的任何地方。但是,当你发现自己在目录之间来回切换,或者在文件系统中“迷路”时,这种速度可能会降低。这些正是 pushdpopd 可以帮助你解决的问题。

pushd

在最基本的情况下,pushd 很像 cd。它可以将你从一个目录带到另一个目录。假设你有一个名为 one 的目录,其中包含一个名为 two 的子目录,而 two 又包含一个名为 three 的子目录,依此类推。如果你的当前工作目录是 one,那么你可以使用 cd 命令移动到 twothree 或任何地方

$ pwd
one
$ cd two/three
$ pwd
three

你可以使用 pushd 执行相同的操作

$ pwd
one
$ pushd two/three
~/one/two/three ~/one
$ pwd
three

pushd 的最终结果与 cd 相同,但还有一个额外的中间结果:pushd 会回显你的目标目录和你的出发点。这就是你的目录堆栈,也是 pushd 独一无二的原因。

堆栈

在计算机术语中,堆栈是指元素的集合。在此命令的上下文中,元素是你最近使用 pushd 命令访问过的目录。你可以将其视为历史记录或面包屑轨迹。

你可以使用 pushd 在文件系统中移动;每次,你之前和新的位置都会添加到堆栈中

$ pushd four
~/one/two/three/four ~/one/two/three ~/one
$ pushd five
~/one/two/three/four/five ~/one/two/three/four ~/one/two/three ~/one

构建堆栈后,你可以将其用作书签集合或快速旅行航点。例如,假设在会话期间,你正在此示例的 ~/one/two/three/four/five 目录结构中进行大量工作。你知道你最近去过 one,但不记得它在 pushd 堆栈中的位置。你可以使用 +0(加号后跟零)参数查看你的堆栈,该参数告诉 pushd 不要更改堆栈中的任何目录,但也提示 pushd 回显你当前的堆栈

$ pushd +0
~/one/two/three/four ~/one/two/three ~/one ~/one/two/three/four/five

或者,你可以使用 dirs 命令查看堆栈,并且可以使用 -v 选项查看每个目录的索引号

$ dirs -v
0  ~/one/two/three/four
1  ~/one/two/three 
2  ~/one
3  ~/one/two/three/four/five

堆栈中的第一个条目是你的当前位置。你可以像往常一样使用 pwd 确认这一点

$ pwd
~/one/two/three/four

从 0(你的当前位置和堆栈的第一个条目)开始,堆栈中的第二个元素是 ~/one,这是你想要的目标位置。你可以使用 +2 选项在堆栈中向前移动

$ pushd +2
~/one ~/one/two/three/four/five ~/one/two/three/four ~/one/two/three
$ pwd
~/one

这会将你的工作目录更改为 ~/one,并且还会移动堆栈,以便你的新位置位于最前面。

你也可以在堆栈中向后移动。例如,要快速到达 ~/one/two/three,给定示例输出,你可以后退一步,记住 pushd 从 0 开始

$ pushd -0
~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four

添加到堆栈

你可以继续以这种方式导航你的堆栈,并且它将保持为你最近访问过的目录的静态列表。如果你想添加目录,只需提供目录的路径。如果目录是堆栈中的新目录,它将像你期望的那样添加到列表中

$ pushd /tmp
/tmp ~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four

但如果它已经存在于堆栈中,它将被再次添加

$ pushd ~/one
~/one /tmp ~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four

虽然堆栈通常用作你想要快速访问的目录列表,但它实际上是你去过的地方的真实历史记录。如果你不希望目录冗余地添加到堆栈中,则必须使用 +N-N 表示法。

从堆栈中删除目录

显然,你的堆栈不是不可变的。你可以使用 pushd 向其中添加项目,或使用 popd 从中删除项目。

例如,假设你刚刚使用 pushd~/one 添加到你的堆栈,使 ~/one 成为你当前的工作目录。要删除第一个(或者如果你喜欢,也可以称为“第零个”)元素

$ pwd
~/one
$ popd +0
/tmp ~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four
$ pwd
~/one

当然,你可以删除任何元素,从 0 开始计数

$ pwd ~/one
$ popd +2 
/tmp ~/one/two/three ~/one/two/three/four/five ~/one/two/three/four
$ pwd ~/one

你也可以从堆栈的末尾使用 popd,同样从 0 开始。例如,要从堆栈中删除最后一个目录

$ popd -0
/tmp ~/one/two/three ~/one/two/three/four/five

像这样使用时,popd 不会更改你的工作目录。它只会操作你的堆栈。

在没有参数的情况下,popd 的默认行为是从你的堆栈中删除第一个(第零个)项目,并将下一个项目设为你的当前工作目录。

当你在两个不同的目录中工作,只需要暂时离开一下去其他位置时,这作为快速更改命令最有用。如果你不需要详细的历史记录,则不必考虑你的目录堆栈

$ pwd
~/one
$ pushd ~/one/two/three/four/five
$ popd
$ pwd
~/one

你也不必快速连续地使用 pushdpopd。如果你使用 pushd 访问不同的位置,然后因追查错误或进行研究而分心三个小时,你会发现你的目录堆栈在耐心地等待(除非你已结束终端会话)

$ pwd ~/one
$ pushd /tmp
$ cd {/etc,/var,/usr}; sleep 2001
[...]
$ popd
$ pwd
~/one

现实世界中的 Pushd 和 popd

pushdpopd 命令非常有用。一旦你学会了它们,你就会找到理由好好利用它们,并且你会熟悉目录堆栈的概念。熟悉 pushd 帮助我理解了 git stash,尽管它与 pushd 完全无关,但在概念上的无形性方面却很相似。

在 shell 脚本中使用 pushdpopd 可能很诱人,但通常最好避免使用它们。它们在 Bash 和 Zsh 之外不具备可移植性,并且当你重新阅读脚本时,它们可能会很晦涩(pushd +3 不如 cd $HOME/$DIR/$TMP 或类似命令清晰)。

除了这些警告之外,如果你是 Bash 或 Zsh 的常规用户,那么你可以并且应该尝试 pushdpopd

接下来阅读什么
Seth Kenlon
Seth Kenlon 是一位 UNIX 极客、自由文化倡导者、独立多媒体艺术家和 D&D 爱好者。他曾在电影和计算机行业工作,而且经常同时工作。

7 条评论

感谢您撰写关于 pushd 和 popd 的文章。我必须记住在经常在目录之间跳转时使用它们。我被一个 pushd 示例卡住了,因为我使用数组的开发工作区分了索引和计数。根据我的经验,零基数组 A、B、C;C 的索引为 2,同时也是第三个元素。C 不会被认为是第二个元素,因为那会混淆它的索引和计数。

有趣的点,Matt。计数和索引之间的差异我之前没有想到,但我会尝试将其内化。这是一个很棒的区别,非常感谢您提出来!

回复 ,作者:matt (未验证)

这看起来像是让我自己困惑的配方。

可能会这样,但从简单开始:使用 pushd 更改到一个目录,然后使用 popd 返回原始目录。有点像一次性使用的书签系统。

然后,一旦你熟悉了 pushd 和 popd,就扩展开来并深入研究堆栈。

我在旧工作中使用的 tcsh shell 没有 pushd 和 popd,所以我过去在我的 .cshrc 中使用函数来模拟来回使用。

回复 ,作者:Greg P

“dirs”也可以用于查看堆栈。“dirs -v”有助于用索引编号每个目录。

感谢你的提示,Jake。我可以说应该将它包含在文章中,但我想尝试只关注两个 {push,pop}d 命令。我没有想到像你在这里所做的那样随意提及 dirs 的一种用法,所以我已经为后人添加了它。

Bash 手册和信息页面中有很多内容可以谈论!

回复 ,作者:Jake

我经常使用“pushd .”(点号表示当前目录)。就像一个工作目录书签,当你在某个地方的几个子目录深处,并且需要 cd 到其他几个地方来做一些工作或检查一些东西时。
由于波浪号扩展,你也可以将 cd 命令与你的 DIRSTACK 一起使用。
cd ~+3 将带你到与 pushd +3 相同的目录。

Creative Commons License本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.