pushd 和 popd 命令是 Bash shell 的内置功能,可帮助你“标记”目录,以便在硬盘驱动器上的不同位置之间快速导航。你可能已经觉得终端是导航计算机的快得不可思议的方式;只需按几下键,你就可以到达硬盘驱动器、连接的存储设备或网络共享上的任何位置。但是,当你发现自己在目录之间来回切换,或者在文件系统中“迷路”时,这种速度可能会下降。这些正是 pushd 和 popd 可以帮助你解决的问题。
pushd
在最基本的情况下,pushd 非常像 cd。它可以将你从一个目录带到另一个目录。假设你有一个名为 one 的目录,其中包含一个名为 two 的子目录,后者又包含一个名为 three 的子目录,依此类推。如果你的当前工作目录是 one,那么你可以使用 cd 命令移动到 two 或 three 或任何位置
$ 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 导航
在没有参数的情况下,popd 的默认行为是从你的堆栈中删除第一个(第零个)项目,并使下一个项目成为你当前的工作目录。
当你例如在两个不同的目录中工作并且只需要暂时离开一下去其他位置时,这最有用作快速更改命令。如果你不需要详细的历史记录,则不必考虑你的目录堆栈
$ pwd
~/one
$ pushd ~/one/two/three/four/five
$ popd
$ pwd
~/one
你也不必连续使用 pushd 和 popd。如果你使用 pushd 访问其他位置,然后因追查错误或进行研究而分心了三个小时,你会发现你的目录堆栈在耐心等待(除非你已结束终端会话)
$ pwd ~/one
$ pushd /tmp
$ cd {/etc,/var,/usr}; sleep 2001
[...]
$ popd
$ pwd
~/one
现实世界中的 Pushd 和 popd
pushd 和 popd 命令非常有用。一旦你学会了它们,你就会找到理由充分利用它们,并且你会熟悉目录堆栈的概念。熟悉 pushd 帮助我理解了 git stash,后者与 pushd 完全无关,但在概念上的无形性方面相似。
在 shell 脚本中使用 pushd 和 popd 可能很诱人,但一般来说,最好避免使用它们。它们在 Bash 和 Zsh 之外不具有可移植性,并且当你重新阅读脚本时,它们可能会很晦涩(pushd +3 不如 cd $HOME/$DIR/$TMP 或类似的命令清晰)。
除了这些警告之外,如果你是 Bash 或 Zsh 的常规用户,那么你可以并且应该尝试 pushd 和 popd。
7 条评论