使用 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.