5.1 快速导航
在命令行下,你如何穿越文件系统的“丛林”而不致迷路?你又如何快速定位所需的文件和目录?如果你仅仅了解导航的基本用法,那么恐怕是不够的。在本节,我将教你几个必备的技能,使你能够轻车熟路的驾驭命令行导航。
5.1.1 回到用户主目录
也许你已经知道 ~
(波浪线) 这个特殊字符代表用户的主目录,若是想要回到自己的主目录,那么我们可以执行:
但是且慢,我想在此告诉你的是,不带任何参数的 cd
命令同样能够将你带回主目录:
换句话说,这两个命令行所达到的效果是相同的。然而,两相比较起来,后者比前者可以少输两个字符,和乐而不为呢?
说到 ~
(波浪线),你还应该了解的一个技巧是,我们可以利用它来转到别的用户的主目录。例如:
我们在 ~
(波浪线) 后面直接跟上 mingji
这个用户名,于是 cd
将我们带到了该用户的主目录。值得注意的是,以下命令行与它并不相同:
请注意 ~
(波浪线) 后的 /
(斜杠),这行命令的作用是转到当前用户主目录下的子目录 mingji
。
5.1.2 回到上次工作的目录
我经常使用的一个导航场景是,在目录 A 中处理了任务之后,接着转到目录 B 中处理任务,一旦完成,我需要再次回到目录 A 继续工作。此时,我们可以执行下面的命令来回到上次工作的目录:
xiaodong@codeland:~$ cd ~/prj/usingcli
xiaodong@codeland:~/prj/usingcli$ pwd
/home/xiaodong/prj/usingcli
xiaodong@codeland:~/prj/usingcli$ cd ~/cli
xiaodong@codeland:~/cli$ pwd
/home/xiaodong/cli
xiaodong@codeland:~/cli$ cd -
/home/xiaodong/prj/usingcli
xiaodong@codeland:~/prj/usingcli$ pwd
/home/xiaodong/prj/usingcli
在此,我第一次工作的目录是 ~/prj/usingcli
,第二次工作的目录是 ~/cli
。通过执行 cd
后跟一个 -
(减号),我们快速的回到了第一次工作的目录。cd -
命令相当于执行 cd "$OLDPWD"
及 pwd
两条命令。
我们还可以继续重复执行 cd -
,这样就会在 ~/prj/usingcli
和 ~/cli
两个目录之间反复切换。
5.1.3 访问常用目录
对于需要频繁访问的深层次目录,直接导航起来感觉还是比较麻烦。幸运的是,bash 和 zsh 两个都为我们提供了 $CDPATH
变量。这是一个与 $PATH
类似的变量,它由 :
(冒号) 分隔的路径列表组成。利用 $CDPATH
,我们能够将常用的目录保存起来,以便 cd
为我们直接转到这些目录。比如:
在这里,我们将 ~
(用户主目录)、~/src
、以及 ~/prj/usingcli
等目录加到了 $CDPATH
中。注意 =
(等号) 后面 :
(冒号) 的左边为空,它表示当前目录,你应当予以保留。否则,在相对路径的情况下 ,cd
就不能转到当前目录下的子目录了。
现在,假如我们打算转到 ~/prj/usingcli/build
目录下的话,那么只要执行下列命令即可:
这个例子同时也告诉我们,加到 $CDPATH
路径列表的目录为待导航的目标目录的父目录。
除了 $CDPATH
变量,zsh 也支持 $cdpath
变量。
5.1.4 自动纠正错误
在用 cd
导航目录时,我们免不了偶尔会输错目录的名称。bash 有一个名为 cdspell
的选项可以帮助我们自动纠正拼写错误,并导航到正确的目录。像是不正确的字母顺序、缺少或者多余的字符等错误,cdspell
都能纠正。
我们在享用如此好的功能之前,需要首先开启 bash 的控制选项:
shopt
命令的 -s
用于启用 cdspell
选项。
现在我们来试一下 cdspell
的效果,我们原本是想要导航到 /etc
目录,但是我们却错输成了 /ect
。不过没有关系,bash 已经帮我们自动纠正了错误,并且转到了正确的目录。
xiaodong@codeland:~$ cd /ect
/etc
xiaodong@codeland:/etc$ cd -
xiaodong@codeland:~$ cd /et
/etc
xiaodong@codeland:/etc$ cd -
xiaodong@codeland:~$ cd /etcd
/etc
xiaodong@codeland:/etc$
在 zsh 中,我们可以给 cd
命令两个参数,它们分别是搜索与替换字符串。zsh 将根据搜索字符串来查看当前工作目录,然后使用第二个字符串替换它,并转到替换后的目录。
xiaodong@codeland:~/cli/1.15.8/src$ pwd
/home/xiaodong/cli/1.15.8/src
xiaodong@codeland:~/cli/1.15.8/src$ cd 1.15.8 1.15.9
xiaodong@codeland:~/cli/1.15.9/src$ pwd
/home/xiaodong/cli/1.15.9/src
本例中,我们的当前工作目录为 /home/xiaodong/cli/1.15.8/src
,cd
命令的第一个参数 1.15.8
跟当前工作目录相匹配。zsh 用 1.15.9
替换了 1.15.8
,然后转到了新的目录 /home/xiaodong/cli/1.15.9/src
。
5.1.5 自动导航
因为 cd
命令是如此常用,我们使用它的频率又那么高,所以 bash 和 zsh 两个都为 cd
命令提供了一个捷径,对像我一样的“懒人”来说,autocd
选项极其有用。
在 bash 中,我们可以通过下面的命令来启用 autocd
选项:
与此对应的 zsh 指令为:
现在假设我们想导航到 ~/prj
目录,代替执行:
我们可以省略 cd
命令,直接执行:
5.1.6 使用目录栈
前面我们讲到的 cd -
允许我们在两个目录之间进行切换,如果我们想要在更多个目录之间切换,那么它就无能为力了。不过,为了帮助我们解决这个问题,bash 和 zsh 提供了目录栈功能。
两个最基本的目录栈命令是 pushd
和 popd
。其中,pushd
命令将一个目录添加到目录栈中,而 popd
命令则从目录栈中移除上次添加的目录。
xiaodong@codeland:~$ pwd
/home/xiaodong
xiaodong@codeland:~$ pushd ~/cli
~/cli ~
xiaodong@codeland:~/cli$ pushd ~/prj
~/prj ~/cli ~
xiaodong@codeland:~/prj$ popd
~/cli ~
xiaodong@codeland:~/cli$ popd
~
xiaodong@codeland:~$
在这个例子中,我们第一次执行 pushd ~/cli
后,将 ~/cli
添加到目录栈的同时,并且转到了该目录。接着,我们继续执行 pushd ~/prj
,又将 ~/prj
目录添加到了目录栈。此刻,我们位于 ~/prj
目录,目录栈中包括 3 个条目:
出栈的顺序跟入栈的顺序相反,第一次执行 popd
命令后,移除了目录栈中的最左边的条目 ~/prj
,并转到了相邻的 ~/cli
目录。再次执行 popd
命令,则又移除 ~/cli
条目,然后转到 ~
目录。
如果你在执行多次入栈与出栈后忘了目录栈中还有哪些条目的话,那么可以执行 dirs -v
命令来查看:
dirs -v
为我们列出了目录栈中的所有条目,每行一条,而且开头具有编号,以便我们引用。例如:
执行 pushd +1
将使 ~/cli
成为目录栈的顶端,并变成当前工作目录。我们可以通过再次执行 dirs -v
命令来确认这一点:
xiaodong@codeland:~/cli$ dirs -v
0 ~/cli
1 ~
2 ~/prj
xiaodong@codeland:~/cli$ pwd
/home/xiaodong/cli
pushd
命令中的 +
(加号) 用于从上往下计数。我们也可以使用 -
(减号) 来从下往上计数。比如:
执行 popd -1
命令后从目录栈中移除了倒数第二个条目 ~
。