Linux 命令行工具使用小贴士及技巧（三）
命令行 导航
在这个系列的[第一部分](/article-8335-1.html)，我们详细地讨论了 `cd -` 命令，在[第二部分](/article-8371-1.html)，我们深入探究了 `pushd` 和 `popd` 两个命令，以及它们使用的场景。


![](/data/attachment/album/201704/08/201121taqbqb0o42xiboix.jpg)


继续对命令行的讨论，在这篇教程中，我们将会通过简单易懂的实例来讨论 `CDPATH` 这个环境变量。我们也会讨论关于此变量的一些进阶细节。


*在这之前，先声明一下此教程中的所有实例都已经在 Ubuntu 14.04 和 4.3.11(1) 版本的 Bash 下测试过。*


### 环境变量 CDPATH


即使你的命令行所有操作都在特定的目录下 - 例如你的主目录，然而在你切换目录时也不得不提供绝对路径。比如，考虑我现在的情况，就是在 `/home/himanshu/Downloads` 目录下：



```
$ pwd
/home/himanshu/Downloads

```

现在要求切换至 `/home/himanshu/Desktop` 目录，我一般会这样做：



```
cd /home/himanshu/Desktop/

```

或者



```
cd ~/Desktop/

```

或者



```
cd ../Desktop/

```

能不能只是运行以下命令就能简单地实现呢：



```
cd Desktop

```

是的，这完全有可能。这就是环境变量 `CDPATH` 出现的时候了。你可使用这个变量来为 `cd` 命令定义基础目录。


如果你尝试打印它的值，你会看见这个环境变量默认是空值的：



```
$ echo $CDPATH

```

现在 ，考虑到上面提到的场景，我们使用这个环境变量，将 `/home/himanshu` 作为 `cd` 命令的基础目录来使用。


最简单的做法这样：



```
export CDPATH=/home/himanshu

```

现在，我能做到之前所不能做到的事了 - 当前工作目录在 `/home/himanshu/Downloads` 目录里时，成功地运行了 `cd Desktop` 命令。



```
$ pwd
/home/himanshu/Downloads
$ cd Desktop/
/home/himanshu/Desktop
$

```

这表明了我可以使用 `cd` 命令来到达 `/home/himanshu` 下的任意一个目录，而不需要在 `cd` 命令中显式地指定 `/home/himanshu` 或者 `~`，又或者是 `../` (或者多个 `../`)。


### 要点


现在你应该知道了怎样利用环境变量 `CDPATH` 在 `/home/himanshu/Downloads` 和 `/home/himanshu/Desktop` 之间轻松切换。现在，考虑以下这种情况， 在 `/home/himanshu/Desktop` 目录里包含一个名字叫做 `Downloads` 的子目录，这是将要切换到的目录。


但突然你会意识到 `cd Downloads` 会切换到 `/home/himanshu/Downloads`。所以，为了确保这不会发生，你可以这样做：



```
cd ./Downloads

```

虽然上述命令本身没有问题，但你还是需要耗费点额外的精力（虽然很小），尤其是每次这种情况发生时你都不得不这样做。所以，有一个更加优雅的解决方案来处理，就是以如下方式来设定 `CDPATH` 环境变量。



```
export CDPATH=".:/home/himanshu"

```

它的意思是告诉 `cd` 命令先在当前的工作目录查找该目录，然后再尝试搜寻 `/home/himanshu` 目录。当然， `cd` 命令是否以这样的方式运行，完全取决于你的偏好和要求 - 讨论这一点的目的是为了让你知道这种情况可能会发生。


就如你现在所知道的，一旦环境变量 `CDPATH` 被设置，它的值 - 或者它所包含的路径集合 - 就是系统中 `cd` 命令搜索目录的地方 ( 当然除了使用绝对路径的场景 )。所以，完全取决于你来确保该命令行为的一致性。


继续说，如果一个 bash 脚本以相对路径使用 `cd` 命令，最好还是先清除或者重置环境变量 `CDPATH`，除非你觉得遇上不可预测的麻烦也无所谓。还有一个可选的方法，比起在终端使用 `export` 命令来设置 `CDPATH`，你可以在测试完当前的 shell 是交互式还是非交互式之后，再在你的 `.bashrc` 文件里设置环境变量，这样可以确保你对环境变量的改动只对交互式 shell 生效。


环境变量中，路径出现的顺序同样也是很重要。举个例子，如果当前目录是在 `/home/himanshu` 目录之前列出来，`cd` 命令就会先搜索当前的工作目录然后才会搜索 `/home/himanshu` 目录。然而，如果该值为 `/home/himanshu:.`，搜索就首先从 `/home/himanshu` 开始，然后到当前目录。不用说，这会影响 `cd` 命令的行为，并且不注意路径的顺序可能会导致一些麻烦。


要牢记在心的是，环境变量 `CDPATH`，就像其名字表达的，只对 `cd` 命令有作用。意味着在 `/home/himanshu/Downloads` 目录里面时，你能运行 `cd Desktop` 命令来切换到 `/home/himanshu/Desktop` 目录，但你不能使用 `ls`。以下是一个例子:



```
$ pwd
/home/himanshu/Downloads
$ ls Desktop
ls: cannot access Desktop: No such file or directory
$

```

然而，这还是有简单的变通处理的。例如，我们可以用以下不怎么费力的方式来达到目的:



```
$ cd Desktop/;ls
/home/himanshu/Desktop
backup backup~ Downloads gdb.html outline~ outline.txt outline.txt~

```

不过，不是每种情况就能变通处理的。


另一个重点是：就像你可能已经观察到的，每次你使用 `CDPATH` 环境变量集来运行 `cd` 命令时，该命令都会在输出里显示你切换到的目录的完整路径。不用说，不是所有人都想在每次运行 `cd` 命令时看到这些信息。


为了确保该输出被制止，你可以使用以下命令：



```
alias cd='>/dev/null cd'

```

如果 `cd` 命令运行成功，上述命令不会输出任何东西，如果失败，则允许产生错误信息。


最后，假如你遇到设置 `CDPATH` 环境变量后，不能使用 shell 的 tab 自动补全功能的问题，可以尝试安装并启用 bash 自动补全（bash-completion）。更多请参考 [这里](http://bash-completion.alioth.debian.org/)。


### 总结


`CDPATH` 环境变量时一把双刃剑，如果没有掌握完善的知识和随意使用，可能会令你陷入困境，并花费你大量宝贵时间去解决问题。当然，这不代表你不应该去试一下；只需要了解一下所有的可用选项，如果你得出结论，使用 `CDPATH` 会带来很大的帮助，就继续使用它吧。


你已经能够熟练地使用 `CDPATH` 了吗？你有更多的贴士要分享？请在评论区里发表一下你的想法吧。


（高清版题图：<http://anguerde.com/TTF-222621-archlinux.html> ）




---


via: <https://www.howtoforge.com/tutorial/linux-command-line-tips-tricks-part-3-cdpath/>


作者：[Ansh](https://www.howtoforge.com/tutorial/linux-command-line-tips-tricks-part-3-cdpath/) 译者：[HaitaoBio](https://github.com/HaitaoBio) 校对：[jasminepeng](https://github.com/jasminepeng)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
# Linux command line navigation tips/tricks 3 - the CDPATH environment variable

In the first part of this series, we discussed the **cd -** command in detail, and the in the second part, we took an in-depth look into the **pushd** and **popd** commands as well as the scenarios where-in they come in handy.

Continuing with our discussion on the command line navigation aspects, in this tutorial, we'll discuss the **CDPATH** environment variable through easy-to-understand examples. We'll also discuss some advanced details related to this variable.

## The CDPATH environment variable

Even if your command line work involves performing all operations under a particular directory - say your home directory - then also you have to provide absolute paths while switching directories. For example, consider a situation where-in I am in */home/himanshu/Downloads* directory:

$ pwd

/home/himanshu/Downloads

And the requirement is to switch to the */home/himanshu/Desktop* directory. To do this, usually, I'll have to either run:

cd /home/himanshu/Desktop/

or

cd ~/Desktop/

or

cd ../Desktop/

Wouldn't it be easy if I could just run the following command:

cd Desktop

Yes, that's possible. And this is where the CDPATH environment variable comes in.You can use this variable to define the base directory for the **cd** command.

If you try printing its value, you'll see that this env variable is empty by default:

$ echo $CDPATH

$

Now, considering the case we've been discussing so far, let's use this environment variable to define */home/himanshu* as the base directory for the [cd command](https://www.howtoforge.com/linux-cd-command/).

The easiest way to do this is:

export CDPATH=/home/himanshu

And now, I can do what I wasn't able to do earlier - from within the */home/himanshu/Downloads* directory, run the *cd Desktop* command successfully.

$ pwd

/home/himanshu/Downloads

$cd Desktop//home/himanshu/Desktop

$

This means that I can now do a cd to any directory under */home/himanshu* without explicitly specifying */home/himanshu* or *~* or *../* (or multiple *../*)in the cd command.

## Points to keep in mind

So you now know how we used the CDPATH environment variable to easily switch to/from */home/himanshu/Downloads* from/to */home/himanshu/Desktop*. Now, consider a situation where-in the */home/himanshu/Desktop* directory contains a subdirectory named *Downloads*, and it's the latter where you intend to switch.

But suddenly you realize that doing a *cd Desktop* will take you to */home/himanshu/Desktop*. So, to make sure that doesn't happen, you do:

cd ./Downloads

While there's no problem in the aforementioned command per se, that's an extra effort on your part (howsoever little it may be), especially considering that you'll have to do this each time such a situation arises. A more elegant solution to this problem can be to originally set the CDPATH variable in the following way:

export CDPATH=".:/home/himanshu"

This means you're telling the cd command to first look for the directory in the current working directory, and then try searching the */home/himanshu* directory. Of course, whether or not you want the cd command to behave this way depends entirely on your preference or requirement - my idea behind discussing this point was to let you know that this kind of situation may arise.

As you would have understood by now, once the CDPATH env variable is set, it's value - or the set of paths it contains - are the only places on the system where the cd command searches for directories (except of course the scenarios where-in you use absolute paths). So, it's entirely up to you to make sure that the behavior of the command remains consistent.

Moving on, if there's a bash script that uses the cd command with relative paths, then it's better to clear or unset the CDPATH environment variable first, unless you are ok with getting trapped into unforeseen problems. Alternatively, rather than using the *export* command on the terminal to set CDPATH, you can set the environment variable in your `.bashrc`

file after testing for interactive/non-interactive shells to make sure that the change you're trying to make is only reflected in interactive shells.

The order in which paths appear in the environment variable's value is also important. For example, if the current directory is listed before */home/himanshu*, then the cd command will first search for a directory in the present working directory and then move on to */home/himanshu*. However, if the value is *"/home/himanshu:."* then the first search will be made in */home/himanshu* and after that the current directory. Needless to say, this will effect what the cd command does and may cause problems if you aren't aware of the order of paths.

Always keep in mind that the CDPATH environment variable, as the name suggests, works only for the cd command. This means that while inside the */home/himanshu/Downloads* directory, you can run the *cd Desktop* command to switch to */home/himanshu/Desktop* directory, but you can't do an *ls*. Here's an example:

$ pwd

/home/himanshu/Downloads$ ls Desktopls: cannot access Desktop: No such file or directory

$

However, there could be some simple workarounds. For example, we can achieve what we want with minimal effort in the following way:

$cd Desktop/;ls

/home/himanshu/Desktop

backup backup~ Downloads gdb.html outline~ outline.txt outline.txt~

But yeah, there might not be a workaround for every situation.

Another important point: as you might have observed, whenever you use the cd command with the CDPATH environment variable set, the command produces the full path of directory you are switching to in the output. Needless to say, not everybody would want to have this information each time they run the cd command on their machine.

To make sure this output gets suppressed, you can use the following command:

alias cd='>/dev/null cd'

The aforementioned command will mute the output whenever the cd command is successful, but will allow the error messages to be produced whenever the command fails.

Lastly, in case you face a problem where-in after setting the CDPATH environment variable, you can't use the shell's tab completion feature, then you can try installing and enabling bash-completion - more on it [here](http://bash-completion.alioth.debian.org/).

## Conclusion

The CDPATH environment variable is a double-edged sword - if not used with caution and complete knowledge, it may land you in some complex traps that may require a lot of your time precious time to get resolved. Of course, that doesn't mean you should never give it a try; just evaluate all the available options and if you conclude that using CDPATH would be of great help, then do go ahead and use it.

Have you been using CDPATH like a pro? Do you have some more tips to share? Please share your thoughts in the comments below.