【问题标题】:How exactly does the cd ./ command work in Bash?cd ./ 命令在 Bash 中究竟是如何工作的?
【发布时间】:2016-01-25 17:05:16
【问题描述】:

我只是好奇,当我在 bash 中使用 cd 命令时,命令

cd foobar

cd ./foobar

以同样的方式工作。我知道,./ 指的是当前的 catalogue 目录,但是为什么“cd foobar”会起作用呢?只是默认,当我一开始不写./时,程序会自己添加它,还是更复杂?

【问题讨论】:

  • 我不确定这是一个关于软件开发而不是用户级语义的问题。将来考虑使用 SuperUser 或 unix.stackexchange.com
  • 你可能想看看这个问题:source code for unix environments 'cd' command
  • 对我来说这似乎是一个完全合理的问题。它应该被视为“以及我需要做什么来实现它”或类似的东西。
  • 如果真正的问题是实现自己的 shell 需要做些什么,那么询问 bash 而不是询问基线 POSIX 规范的要求就是为自己做大量的额外工作。

标签: linux bash unix scripting cd


【解决方案1】:

bash 中的cd 命令(有点间接,如下所述)调用chdir() 系统调用behavior of which is specified by POSIXcd shell 命令本身和also has a POSIX specification for its behavior,可能比可访问/可读定义更详细。

是的,所有操作(不仅是chdir(),还有fopen() 和其他操作)的默认值都是当前工作目录。

这不是特定于 bash,而是操作系统级别的行为:“当前工作目录”是有关内核跟踪的每个进程的元数据的一部分,并且会影响向内核发出的文件系统级别的请求:任何任何语言的程序都可以调用chdir("foo")open("foo", O_RDONLY),行为将是在当前目录中查找foo,从父进程继承或使用先前的chdir() 调用修改。


也就是说,就 bash 而言,cd ./foo 比仅仅 cd foo 更具体:前者表示您明确想要当前工作目录的 foo 子目录。在 bash 中,如果设置了CDPATH shell 变量,那么cd foo 将查找其中列出的所有目录,而cd ./foo 显式只要求当前工作目录下的foo

试试这个实验:

# setup
tempdir=$(mkdir -d "${TMPDIR:-/tmp}/cdpath-test.XXXXXX")
mkdir -p "$tmpdir/i-am-a-test-directory"
CDPATH=".:$tempdir"

# this works, because CDPATH is honored
cd /
cd i-am-a-test-directory

# this does not, because you're explicitly asking for a directory that does not exist
cd /
cd ./i-am-a-test-directory

# cleanup
rm -rf "$tempdir"
unset CDPATH

【讨论】:

    【解决方案2】:

    暂时忽略CDPATH这个环境变量,cd后面的名字是目录路径名。 Unix 中只有两种路径名:

    • / 开头的绝对名称
    • 不以/ 开头的相对名称

    内核将所有相对名称视为相对于当前目录的相对名称 — 就好像名称以 ./ 为前缀。

    如果您设置了CDPATH,它会使搜索复杂化,然后可以想象cd somewherecd ./somewhere 将您置于不同的目录中。没有前导 / 并且没有前导 ... 组件的目录名称(其中 cd .hidden 不计算 - 前导组件是 .hidden - 但 cd ./visiblecd ../visible 计算)使用CDPATH 搜索。

    例如,考虑这个树结构(仅显示目录):

    .                - current directory
    ./somewhere
    ./src
    ./src/somewhere
    

    假设你有CDPATH=src:。然后cd somewhere 将转到./src/somewherecd ./somewhere 将转到(不出所料)./somewhere。如果您键入诸如cd src/somewhere 之类的名称,cd 命令将依次在CDPATH 上为每个目录/xyz/pqr 搜索子目录/xyz/pqr/src/somewhere。我永远使用CDPATH(我自己的机器上有7个目录;我的工作机器上有14个目录)。

    • 经验法则:使用CDPATH=:…whatever…

    这会将当前目录放在搜索路径的首位,这通常是最理智的行为。

    类似的情况也适用于搜索普通的外部(非别名、非函数、非内置)命令。以斜杠开头的命令名是绝对路径名;包含斜杠的命令名称是相对于当前目录的;在 $PATH 上搜索不带斜线的命令名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-03
      • 2023-04-01
      • 2013-02-12
      • 2011-06-26
      • 2021-08-15
      • 2012-06-08
      • 2011-10-11
      相关资源
      最近更新 更多