是否cd。有用吗?


102

我一直关注的其中一篇教程简要说明了cd .它没有用。尝试复制符号链接递归中 OP所示的问题时-是什么使其“重置”的?,我也尝试过cd .,它显示出与OP相同的效果(不断增长的$PWD变量),可以用抵消cd -P

这使我感到奇怪,实际上是否有任何人想使用它cd .


20
我有一个自定义.zshrc,当切换目录时,它将在目录上运行各种检查,例如,其中一项检查是在移动目录时自动激活/停用匹配的virtualenv。有时,我可能会启动一个新的Shell或其他任何程序,而这些检查不会运行,并且我通常cd .会触发这些检查,因为它既简短又简单。尽管我认为您打算将问题针对原始环境。
Lie Ryan

29
除了对的(明显)影响外$PWDcd .还更改$OLDPWD为当前目录。我(目前)不知道为什么这可能有用,但是为了完整起见……
Andreas Wiese

5
我认为我永远都不需要cd .,尽管看到下面的答案,我将来可能会用到,但是有时pushd .我想在以后能够popd返回到该目录时使用它。例如,运行运行configurecd output...和的构建脚本make时,以及完成后,我想回到原始目录。我不必维护自己的不同于其他所有人期望的buildscript副本,而只是将其运行为pushd .; ./BuildScriptName.sh; popd,这也使我有自由,popd有时甚至popd以后没有。
3D1T0R

5
当然不要说“。” 和'..'并不是在cd命令本身中实现的,因此没有人提出要实现该特定功能的功能,但这只是无用的组合。
David S

1
@ruakh不,外部程序不应影响shell执行环境。它主要用于POSIX合规性,它要求某些实用程序存在于Shell外部,并评估外部命令的退出状态。您可以在/bin/cd此处了解unix.stackexchange.com/q/50058/85039
Sergiy Kolodyazhnyy

Answers:


158

我认为这是对问题的思考。cd .可能不是通常情况下手动运行的东西,但是绝对可以在程序执行中出现(想想在任何情况下,您可能会cd进入包含文件的目录,该目录的路径由用户提供) )。因此,它不必具有特定用途:只要它满足的通常语义cd <some-path>,它就很有用。


12
同意, .应将其视为由cd语法指定的有效路径就可以了。
Sergiy Kolodyazhnyy

18
您可以添加以下示例:像while一样的循环IFS= read Dir; do cd "$Dir"; do_something; done < <(find . -type d)。在查找过程中,find将产生.为路径,因此命令cd "$Dir"将扩展为cd .。因此,在脚本中,它非常有用。
rexkogitans

5
例如,一个脚本实际上在运行cd ${path_to_directory},但在某个时候它证明该目录是当前目录,path_to_directory = .因此您需要cd .进行工作以防万一。
Demis

4
换句话说,它的实用性在于它不需要额外的代码(if检查和else子句,任何特殊的大小写)。
jpmc26

2
因此,从x + 0或x * 1有用的意义上讲,这很有用-特定的操作本身并不有用,但这意味着您可以将0和1与其他任何值一样处理,而不必将它们视为特例。
user32929

127

自从执行最后一条命令以来,目录的路径可能已更改,并且没有cd .bash和ksh93 shell将依赖于问题链接中所描述的帖子中描述的逻辑工作目录,因此cd .,使shell发出getcwd()syscall的调用将确保您使用当前路径仍然有效。

重现bash的步骤:

  1. 在终端标签中 mkdir ./dir_no_1; cd ./dir_no_1
  2. 在另一个终端选项卡中 mv dir_no_1 dir_no_2
  3. 在第一个终端标签中,发出echo $PWDpwd。请注意,该目录已在外部重命名;外壳的环境尚未更新。
  4. 问题cd .; pwd; echo $PWD。注意该值已更新。

但是,ksh93不会更新环境信息,因此cd .在ksh93中实际上可能没有用。在/bin/dashUbuntu和其他基于Debian的系统上,cd .返回dash: 3: cd: can't cd to .错误,但是cd -P .可以工作(与ksh93不同)。


22
提提您:我会将其添加到我的无用信息列表中。^^)
jayooin

12
@jayooin很高兴我可以为列表做出贡献;)
Sergiy Kolodyazhnyy

8
我认为您可以mv ../dir_no_1 ../dir_no_2同一终端/ bash中进行操作。
ctrl-alt-delor

3
@ ctrl-alt-delor确认,工作:)
Sergiy Kolodyazhnyy

1
@ymbirtt实际上在大多数shell中pwd都是内置的,但是调用/bin/pwd对shell环境没有影响-外部实用程序通常不会影响shell环境。为什么原因/bin/cd/bin/pwd存在是POSIX一致性,等等。有一个关于外部CD好了就讨论其中的一些可能适用于/bin/pwd以及
谢尔盖Kolodyazhnyy

55

的另一个用例cd .是当您当前所在的目录被删除然后重新创建时。考虑尝试以下方法-

  1. 建立目录 temp
  2. cd temp 然后做一个 ls
  3. 打开另一个终端并删除,然后重新创建该目录 temp
  4. 从第一个终端返回,尝试执行ls。这将导致错误-ls: cannot open directory .: Stale file handle
  5. cd . 然后做ls就可以了

3
这并不总是有效。例如,在破折号中,您将获得:cd: can't cd to .现在,我看了一下,这已经在Sergiy的答案中提到(移动,删除/重新创建-本质上是相同的:您所在的目录不再是原始目录中的目录)路径)
Olorin

12
我经常用它来测试远程部署。我所在的目录将被删除,然后通过一些自动化操作重新创建,我将需要发出命令cd .以移至同名的新目录。
HP Williams

2
我一直使用cd .具有其当前工作目录已通过sshfs挂载的shell,但ssh会话已关闭并重新打开的所有时间。
jamesdlin

4
在这种情况下,我会执行“ cd $ PWD”。其他变体也可能起作用,但是该变体明确表达了其意图:提取应该是我当前的路径(即读取PWD环境变量的内容),然后从根目录遍历文件系统层次结构,直至恰好可以通过以下方式访问的目录:该路径,实际上是否是同一目录。这恰好适合此答案中的用例。
斯特凡纳·古里科

3
cd .当目录取消链接并且在同一文件系统路径上创建新的不同目录时,我真的很惊讶,甚至震惊。当前工作目录已取消链接,并且大概是其中的一部分,它不再具有...条目,即使存在,该.条目也应继续指向自身。看起来Shell或内核正在根据目录路径名而不是简单地访问.条目来执行cd命令。有人可以确认这种行为吗?
Adrian Pronk

36

如果需要在某些情况下不希望它指向“有趣”的任何地方,则可以$OLDPWD快速清除cd .。它也会影响cd -


16

从编程上讲,它是无操作的有用。考虑从外部输入提供的路径。

read -p "Path to file: " p
dirn=$(dirname "$p")
file=$(basename "$p")
echo "dirn=$dirn, file=$file"
cd "$dirn"
ls -ld "$file"

使用“ fred.txt”之类的路径,目录将变为.,从而导致cd .


1
如果您已经在要导航的目录中,那么它不会引发错误是很有用的,但是我不会说它作为无操作者很有用。
曼队长

2
如果您已经在目录中,则@CaptainMan不会抛出错误(有效)是无操作。该dirname命令.在必要时生成,以避免破坏期望能够拆分路径的代码。
roaima

15

如果必须使用不良的USB电缆,这很常见。设备断开连接并重新连接,并自动挂载到同一目录后,必须使用cd .它才能使其重新工作。


1
这是否取决于哪种设备,如何访问它,其文件系统,操作系统以及&c?
gidds

操作系统,也许吧。只要内核可以在使用文件系统时找到卸载方法,文件系统就不太可能相关。在任何情况下,该命令都会在完全正确的情况下使用。
user23013

11

注意 ”。” 将打开的文件的名称指定为任何进程(当然包括shell进程)的当前工作目录的正确方法,以及“”。始终是任何目录(包括当前工作目录)中文件的有效名称。.如果已删除基础的当前工作目录(或变为“坏的”(例如,陈旧的NFS句柄)),则该名称可能不是给定流程实例的文件的有效名称,但它是有效名称确保在每个有效目录中都存在的文件的名称。

因此,对于任何接受目录名称的命令,. 必须为有效参数,因此,在标准外壳程序中,cd .必须为有效命令。

是否cd .有用取决于shell实现。如前所述,如果外壳程序在调用基础chdir系统调用后重置其对当前工作目录的完整路径名的内部概念,这可能很有用,例如说基础目录(或其某些父目录)是否已重命名。

我知道至少有一些shell(/bin/sh在FreeBSD和NetBSD上)会转换cd ""cd .,可以说可以描述为一种功能,以支持在shell脚本中以编程方式使用,其中可以将变量用作参数(即,将空变量替换为“不执行任何操作”的结果),尽管FreeBSD提交历史记录指出,更改直接是由于添加了POSIX支持以防止失败chdir(""),而POSIX任务必须失败。

其他一些shell将.使用存储为当前工作目录的标准路径名的内容替换掉它们,因此对于他们来说,这可能允许Sahil Agarwal的答案中提到的行为。


4

就在今天,当我在最初在同一分支上创建的目录中重新建立我在Git中工作的分支的基础时,才使用此命令。重新设置很好,但随后又git status出错了。后cd .一切正常。

(偶然地,我在Windows上的MobaXterm中工作。以防万一,您试图重现此代码。在其他系统上可能不会发生。)


我还在已由自动过程刷新的目录中使用了此命令,该过程将旧目录移开并用新目录替换(因此,它尽可能接近于原子目录)。这不是常见的情况,但这cd .正是需要的。


在阅读完Stephane Chazelas的出色回答后:

我现在明白,我上面的用例只能因为我正在使用而起作用bashcd .相当于cd "$PWD"。我强烈建议您阅读链接的答案。


1

cd .过去经常cd通过bash函数重新运行已经超载的东西。

来自我~/.bashrc

# from the "xttitle(1)" man page - put info in window title
update_title()
{
    [[ $TERM = xterm ]] || [[ $TERM = xterm-color ]]  && xttitle "[$$] ${USER}@${HOSTNAME}:$PWD"
}

cd()
{
    [[ -z "$*" ]] && builtin cd $HOME
    [[ -n "$*" ]] && builtin cd "$*"
    update_title
}

0

编辑:这已经由萨希尔以前建议。

如果您位于一个已被另一个进程删除并重新创建的文件夹内,这将很有用。例如,假设有两个终端会话$1$2

$1 mkdir d
$1 cd d
$1 touch f

$2 rm -rf /path/to/d # delete the folder where $1 is in ...
$2 mkdir /path/to/d # ... and recreate it

$1 touch g # cannot create file g because current dir doesn't exist anymore
touch: cannot touch ‘g’: Stale file handle
$1 cd . # go to the newly created dir (same path)
$1 touch g # works fine now

我不确定此行为的根本原因到底在哪里(OS,SHELL,...?)。


其他答案已经提到了这一点。
库萨兰达

-8

不,没有道理。无论是在脚本编写中,它什么都不做。


2
根据外壳程序的不同,它将重置$PWD,如果用户提供了自己的cd函数或别名以使内建程序过载,则它可能会调用其他外壳程序函数cd。它还将验证当前目录仍然有效,并且当前使用有权访问该目录。
库萨兰达

1)当然,我们不是在谈论“ cd”的可能的自定义别名,而是标准的版本2)如果没有许可,当前的使用方式将如何存在?为了简单起见,我只是说在我的现实世界中没有理由使用它。
费德里科

1
1)不是吗?2)现实世界并不简单,Unix是一个多用户操作系统。用户可以更改目录的权限,如果脚本或其他用户的交互式外壳恰好具有该目录(或其子目录)作为其工作目录,cd .则会抱怨。
库萨兰达

4
费德里科(Federico),根据网站规则和我自己的个人规则,我应该拒绝您的回答。但是,您是新手。欢迎!请查看其他一些答案。之后,如果您认为答案有误,请删除它。请享受给这个问题和其他问题的其他答案。
daveloyall

2
特别是在脚本编写中,有时“无所事事”正是需要的。
马修·纳荷蒙
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.