在虚拟机中执行 cd 命令切换目录,本质上是客户操作系统(Guest OS)里的 Shell 进程修改自身的工作目录,整个过程由虚拟化层透明转发或直接由客户内核处理,和你物理机上敲命令没有区别。 这个动作看似简单,但放到虚拟机语境下,涉及 Shell 内建机制、系统调用、虚拟化层对特权指令的拦截方式,以及跨平台路径兼容等多个层面的细节。
虚拟机 cd命令 切换目录的常见用法与参数详解
既然要聊虚拟机里的 cd,我们先把手头的姿势理顺,无论你用的是 VMware Workstation、VirtualBox 还是 KVM,只要进入了客户机的终端,cd 的用法就是标准的 POSIX 风格。
- 绝对路径切换:
cd /var/log直接跳转到根目录下的var/log,这是最稳妥的写法,不管当前在哪个目录,结果都可预期。 - 相对路径切换:
cd ./scripts或cd ../config,相对路径依赖当前所在位置,在脚本里需要格外小心,因为当前目录变了,结果就跟着变。 - 回到用户主目录:
cd不加任何参数,或者cd ~,直接回当前用户的家目录,这个快捷方式在虚拟机里非常常用,尤其是从/etc这类深层目录逃出来的时候。 - 回到上一次目录:
cd -会在当前目录和上一次所在目录之间来回跳转,配合pwd查看路径,效率很高,属于老手常用的手法。 - 处理带空格的目录名:
cd "/mnt/hgfs/My Shared Folder"或者用反斜杠转义空格,cd /mnt/hgfs/My\ Shared\ Folder,虚拟机共享文件夹的路径里经常有空格,这个坑很常见。 - 跨盘符切换(Windows 虚拟机):在 Windows 客户机里,
cd切换盘符需要加/d参数,cd /d D:\Tools,如果不加,你敲完cd D:\之后,当前盘符还是 C 盘,光标位置不变,这很容易让人误以为命令没生效。
下面用一张表对比不同场景下的 cd 写法,方便你查阅:
| 场景 | 命令写法 | 适用环境 |
|---|---|---|
| 回到用户主目录 | cd 或 cd ~ |
Linux/Unix 虚拟机 |
| 回到上一次目录 | cd - |
Linux/Unix 虚拟机 |
| 切换盘符并进入路径 | cd /d D:\data |
Windows 虚拟机 |
| 进入带空格的目录 | cd "/root/My Files" |
所有虚拟机 |
| 回到上一级目录 | cd .. |
所有虚拟机 |
虚拟机 cd命令 切换目录的原理:从 Shell 内建到内核调用
要弄懂 cd 在虚拟机里的实现原理,得先明白一个关键点:cd 不是外部程序,而是 Shell 的内建命令(builtin),你可以用 type cd 查看,输出结果是 cd is a shell builtin,而不是某个 /bin 下的可执行文件,这并非设计者偷懒,而是有一个硬性原因在背后。
为什么 cd 必须是内建命令?
在 Linux 和类 Unix 系统里,每个进程都有独立的“当前工作目录”(Current Working Directory),这个目录是进程的属性,子进程不会继承父进程的“当前目录变更”结果子进程只能继承父进程启动那一刻的目录快照,如果把

cd 做成 /bin/cd 这样的独立可执行文件,那么当你敲下 cd /var/log 时,Shell 会 fork 出一个子进程来执行这个文件,子进程的 chdir() 系统调用只改变了子进程自己的工作目录,子进程退出后,Shell 自己的工作目录纹丝不动,结果就是你敲了回车,目录却变了,命令完全无效。
cd 必须由 Shell 自己“消化”掉,Shell 内部直接调用 chdir() 这个系统调用,把自身进程的工作目录改掉,这个过程不涉及任何新的进程创建,也没有额外的 I/O 开销。
系统调用在虚拟机里怎么走?
现在我们来回答“虚拟机指令 cd 如何切换目录”这个核心问题,当你在客户机终端的 Shell 里输入 cd /data 并回车,事情是分几步走的:
- Shell 解析命令行,识别出
cd是内建命令,不再去PATH路径里找可执行文件。 - Shell 调用
chdir("/data")系统调用,把当前进程(Shell 自己)的工作目录切换到/data。 - 在虚拟机里,这个
chdir请求会通过客户机操作系统内核,如果当前指令不涉及特权操作,虚拟处理器的硬件虚拟化扩展(如 Intel VT-x)会直接让客户机内核处理,不需要宿主机插手。 - 只有当执行到敏感指令或特权指令时,CPU 才会触发 VM-exit,把控制权交给宿主机 Hypervisor 处理。
chdir这种普通目录操作不在此列。
行业共识认为,虚拟化层对 chdir 这类文件系统操作的影响微乎其微,因为目录管理属于客户机内核的文件系统子系统的职责,这个子系统直接操作虚拟磁盘上的文件系统元数据,处理流程与物理机上的逻辑完全相同。
OLDPWD 的巧妙设计
cd - 能回退到上一个目录,靠的是一个叫 OLDPWD 的环境变量,Shell 在每次成功切换目录前,会把当前目录路径记录到 OLDPWD 变量里,然后把新路径设置到 PWD 变量中,当你执行 cd - 时,Shell 读取 OLDPWD,再次调用 chdir() 切换过去,同时交换两个变量的值,这个机制在虚拟机里同样有效,因为环境变量存储在客户机 Shell 进程的内存里,不涉及虚拟化层。
虚拟机 与 容器 目录切换有什么本质区别?
聊到虚拟机,很多朋友会想把它和容器做对比,当你问“虚拟机 与 容器 目录切换有什么本质区别”时,答案其实指向了虚拟化的层级。
虚拟机有完整的客户机内核,你 cd 切换目录时,操作的是客户机内核里挂载的文件系统,里面包含完整的虚拟磁盘分区、挂载点、inode 表,即使两个虚拟机共享宿主机上的同一个物理磁盘文件(VMDK 或 qcow2),它们之间的目录树依然是各自独立的,互不可见。
容器则直接共享宿主机内核,在容器里执行 cd /app,底层调用的是宿主机内核的 chdir 系统调用,只是通过命名空间(namespace)实现了“看起来像独立目录树”的效果,容器的根目录可能是宿主机上的某个 .local 子目录,你 cd /app 实际进入的是宿主机上的 /var/lib/docker/overlay2/xxx/merged/app。
从命令本身来看,cd 在两种环境里的语法完全相同,但排查问题的路径不同,虚拟机里目录消失,可能是虚拟磁盘文件损坏或挂载失败;容器里目录内容不对,往往是镜像层或卷挂载配置出了问题。

虚拟机上目录切换失败的真实场景排查
虚拟机里的 cd 命令偶尔会“失灵”,多数情况不是命令本身的问题,而是环境配置在捣乱,下面几个场景是我在实操中经常遇到的。
从 Windows 宿主机拖过去的脚本,CD 报“No such file or directory”
这个问题相当典型,你在 Windows 上用记事本写了一个 deploy.sh,第一行是 cd /opt/app,然后通过 VMware Tools 共享文件夹或拖拽放进 Linux 虚拟机,执行时提示找不到目录,你手动输入同样的命令却完全正常。
原因不是目录不存在,而是脚本文件包含了 Windows 风格的 CRLF 行尾符,Shell 读到的 cd /opt/app\r,\r 被当成目录名的一部分,自然找不到路径,解决方法是安装 dos2unix 工具,执行 dos2unix deploy.sh,或者在 Vim 里执行 set fileformat=unix 后保存。
cd 到共享文件夹,提示“Transport endpoint is not connected”
VMware 的共享文件夹挂载在 /mnt/hgfs/ 下,当你 cd /mnt/hgfs/share 却报错时,大概率是 VMware Tools 服务挂掉了,重启一下服务即可:
sudo vmware-tools-services.sh restart
或者更现代的做法,重新挂载共享文件夹:
sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other -o uid=1000
在 Windows 虚拟机里 cd 到另一个盘符没反应
上面提到过,Windows 的 cd 默认不跨驱动器切换,你敲 cd D:\ 后,提示符还是 C:\Users\xxx>,这是 cmd.exe 的老规矩,没什么原理可讲,加 /d 开关就能解决,如果你想在 PowerShell 里切换,cd D:\ 是直接可用的,它的工作目录切换逻辑和 cmd 不同。
Shell 脚本里 cd 后看不到效果
有一个比较隐蔽的坑是,在 Linux 虚拟机里写一条简单的脚本命令:
cd /opt/app java -jar app.jar
/opt/app 目录在脚本执行的瞬间不存在(比如前面的解压步骤失败了),脚本会继续执行下一行,但当前目录还在脚本原始位置,导致 java 命令报“找不到 jar 包”或者“Could not find or load main class”。
应对办法是使用逻辑连接:
cd /opt/app && java -jar app.jar
这样写,cd 失败时后续命令不会执行,错误能被立刻暴露。
结合自动化运维使用 cd 命令的几个实用建议
在虚拟机的自动化部署、批量初始化场景里,cd 是一个高频出现的命令,但越是高频,越容易被人忽视其中的风险,国内企业跑虚拟化集群时,运维脚本里 cd 用法往往直接决定任务成败。
- 多用绝对路径,少用相对路径:自动化脚本的初始工作目录是调用方决定的,不可控因素太多,绝对路径
cd /data/apps/web可以消除歧义,也不受调用方目录影响。 - 使用
&&串联操作:cd /opt/nodejs && npm install可以保证目录切换成功后再执行安装,避免出现“找不到 package.json”这类排查成本高的报错。 - 用子 Shell 隔离目录变更:
(cd /data && tar -xzf backup.tar.gz)把cd放在括号里,目录切换在子 Shell 中完成,不会影响父 Shell 的当前目录,多用于脚本中需要临时进入某目录,但不能污染主流程目录的场景。 - 检查 CD 的返回值:在需要严谨逻辑的脚本中,可以用
cd /path || exit 1显式终止执行。

虚拟机 切换目录 命令 是什么以及有哪些易混淆点
很多人会把 cd 和 pwd、ls 搞混,或者把宿主机的目录映射和客户机的路径直接对应起来,这里梳理几个高频易混淆点。
- 宿主机的目录不等于客户机的目录:你在 VMware 里把宿主的
D:\web共享给虚拟机,客户机看到的路径是/mnt/hgfs/web,不能直接在客户机里输cd /d/web,除非你把宿主的D:\web通过分区直通等手段映射成了客户机的/d/web,这在普通配置里是不成立的。 cd和pwd是一对:cd负责切换,pwd负责确认当前结果,遇到目录切换后不确定定位的情况,敲一下pwd看输出,算是最直接的诊断手段。- 的展开是 Shell 的活儿:
cd ~/downloads里波浪号的展开发生在 Shell 解析阶段,不是chdir()做的,如果换成脚本执行, 不一定能正确展开到目标用户的家目录,用$HOME更稳妥。
很多人关心的日常问题是“linux cd命令 切换目录 原理”是否会在虚拟机里因为半虚拟化驱动而变慢。chdir 需要更新进程的 /proc/self/cwd 符号链接以及文件系统引用计数,这些都在客户机内核的 VFS 层完成,虚拟磁盘的预读缓存会缓存目录项,多数情况下切换成本极低,不会成为虚拟机性能瓶颈,关于这方面的原理说明,用户可以参考 man chdir 和 Linux 内核文档中关于 VFS 层的描述,不需要额外深挖虚拟化硬件的具体行为。
Q&A:关于虚拟机 cd 切换目录的常见疑问
为什么在虚拟机里执行 cd 到一个不存在的路径没有任何输出?
cd 命令默认是静默的,成功时不输出任何内容,失败时会向标准错误输出一行提示信息,如果你执行的 cd /nonexistent 什么反应都没有,一种可能是路径确实存在但你没有感知到,另一种是你的 Shell 设置了 cdable_vars 之类的选项导致行为变化,用 pwd 确认当前目录,用 ls -ld /nonexistent 检查路径是否存在,就能判断问题所在。
cd 命令在虚拟机中与物理机相比有区别吗?
没有区别。cd 是 Shell 的内建命令,它调用的 chdir() 系统调用在虚拟机内部由客户机内核直接处理,虚拟化层的作用主要体现在 CPU 指令翻译和 I/O 设备模拟上,目录切换这种纯软件层面的内存操作不会触发特权指令,因此耗时和逻辑都和物理机一致,差别只可能出现在虚拟机特有的挂载层(如共享文件夹、动态磁盘扩展)导致路径延迟出现或消失的场景。
为什么在 shell 脚本里 cd 之后,脚本的工作目录没变?
因为你的 cd 可能执行在一个子 Shell 中,比如用管道或括号包裹命令时,Shell 会创建子进程来执行,子进程调用 chdir() 只改变子进程自己的目录,父进程不受影响,解决方法是使用 source(或 )执行脚本,让命令在当前 Shell 进程中运行,或者在脚本顶层直接使用 cd 而不加括号,这也是自动化任务中常见的坑,属于 Shell 进程模型的基础约束。