“cd -”和“cd ~-”的区别

dr_*_*dr_ 71 bash directory cd-command pushd

bash 命令

cd - 
Run Code Online (Sandbox Code Playgroud)

打印以前使用的目录并对其进行更改。

另一方面,Bash 命令

cd ~-
Run Code Online (Sandbox Code Playgroud)

直接更改到以前使用的目录,不回显任何内容。

这是唯一的区别吗?每个命令的用例是什么?

ter*_*don 100

这里有两件事在起作用。首先,将-单独扩展到您以前的目录。这在(强调我的)cd部分中有解释man bash

-在尝试更改目录之前,将的参数转换为 $OLDPWD。 如果使用 CDPATH 中的非空目录名,或者如果-是第一个参数,并且目录更改成功,则新工作目录的绝对路径名将写入标准输出。 如果目录更改成功,则返回值为真;否则为假。

因此,一个简单的操作cd -会将您移回之前的目录并打印出该目录的名称。另一个命令记录在“波浪号扩展”部分:

如果波浪号前缀是 a ~+,则 shell 变量 PWD 的值将替换波浪号前缀。如果波浪号前缀是 a ~-,则替换外壳变量 OLDPWD 的值(如果已设置)。如果波浪号前缀中波浪号后面的字符由数字 N 组成,可选地以 a +或 a-为前缀,则波浪号前缀将替换为目录堆栈中的相应元素,因为它将由调用的 dirs 内置函数显示波浪号前缀作为参数。如果波浪号前缀中波浪号后面的字符由没有前导+或的数字组成-+则假定。

举个例子可能更容易理解:

$ pwd
/home/terdon
$ cd ~/foo
$ pwd
/home/terdon/foo
$ cd /etc
$ pwd
/etc
$ echo ~        ## prints $HOME
/home/terdon
$ echo ~+       ## prints $PWD
/etc
$ echo ~-       ## prints $OLDPWD
/home/terdon/foo
Run Code Online (Sandbox Code Playgroud)

所以,一般来说,-意思是“上一个目录”。这就是为什么cd -它本身会带你回到你所在的地方。

主要区别在于cd -特定于cd内置。如果您尝试,echo -它只会打印一个-. 这~-是波浪号扩展功能的一部分,其行为类似于变量。这就是为什么你可以echo ~-并得到一些有意义的东西。您也可以在 中使用它,cd ~-但也可以在任何其他命令中使用它。例如cp ~-/* .,这相当于cp "$OLDPWD"/* .

  • `set -x` 在执行之前打印扩展的命令可能有助于说明差异(或者当你不自己一步一步地做时可能会产生难以理解的噪音)。 (2认同)
  • @terdon 今天我学会了。 (2认同)
  • 简而言之... `cd ~-/..` 有效,`cd -/..` 无效! (2认同)

cho*_*oba 15

~-受波浪号扩展(参见 man bash),所以cd直接看到的是以前的目录名称。-没有被 shell 展开,cd直接看到它,并且表现得如文档所示:

- 的参数等效于 $OLDPWD。如果使用 CDPATH 中的非空目录名,或者如果 - 是第一个参数,并且目录更改成功,则新工作目录的绝对路径名将写入标准输出。


Hen*_*eld 5

TL;DR:cd -内置于 中cd~-是 的后期扩展~[name],并非特定于cd.

POSIX.1-2008 Shell & Utilities定义cd -特定cd命令的特殊情况:

当 a-用作操作数时,这应等效于以下命令:

cd "$OLDPWD" && pwd

它更改为以前的工作目录,然后写入其名称。

~-扩展将扩大到$OLDPWD在执行任何命令之前,可以作为任何命令的参数,而不仅仅是传递cd。它是的后续扩展。

前面提到的 POSIX.1-2008 Shell & Utilities 标准也有对 Tilde Expansion 的详细解释。措辞非常具体,以允许~-标准范围内的未定义行为,其中~[name]指的是$HOMEif[name]是空字符串,或者用户的主目录nameifname是有效的用户名。