news 2026/9/28 5:16:42

详解Linux cd命令:从基础用法到脚本安全技巧

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
详解Linux cd命令:从基础用法到脚本安全技巧

只要你用过终端,就逃不掉cd这个命令。它全称change directory,中文叫切换目录,是命令行世界里最基础也最容易被当成“常识”跳过的东西。我见过不少同事在Linux服务器上跑了几年,cd的用法还停留在cd xxx、cd ..、和cd /三板斧上。这当然不算错,但如果你愿意花二十分钟把cd真正吃透,写脚本、查日志、找配置文件的整个节奏都会明显顺一截。

这篇文章打算把cd这件“小事”讲透:不同Shell里的标准写法、几个帮你偷懒的隐藏开关、实战中的切换技巧,以及各种让人摸不着头脑的报错排查。不管是刚摸终端的新手,还是每天在命令行里泡着但偶尔被路径坑一把的老手,应该都能从这里拿点东西走,至少以后看到cd开头的报错,不会再一脸懵地重启机器。

先打个预防针:cd这个关键词太容易撞词了。圈里聊CI/CD时它指的是持续交付(Continuous Delivery),游戏玩家嘴里它又是技能冷却(Cooldown),Windows装系统时还可能是指光盘。为了避免误会,先声明一下——我全文只讲命令行里那个最朴素的cd,也就是切换当前工作目录。

1. 先搞清楚:cd切来切去,到底在切什么

1.1 工作目录,其实是每个进程的“工位坐标”

当你敲下cd /etc/nginx,做的事情不是“看一眼”这个目录,而是把当前Shell进程的工作目录(Working Directory)整个换到了/etc/nginx。这个工作目录是操作系统给每个进程维护的属性,内核时刻记着“你正在哪个目录里”。你执行的任何相对路径命令,都以这个目录为起点去找文件。所以我说它是工位坐标一点不夸张:你人在哪个工位,你伸手能拿到的文件、命令默认去哪些地方找东西,全由它决定。

用生活类比更好理解:你在公司办公,敲命令就像在工位上干活的你。cd就是换工位。你敲ls,等价于低头看看自己工位抽屉里有什么;你敲vim xxx,等价于在工位附近找某个文件打开。工位换了,目之所及的范围自然就变了。

这也解释了一个很多人问过的问题:为什么which cd查不到、或者显示cd is a shell builtin?因为cd必须是Shell自己执行的内建命令,而不是外部程序。假设cd是一个外部程序,你敲下它之后,Shell会先派一个子进程去执行,子进程确实能把自己挪到目标目录,但子进程一退出,你的Shell父进程还留在原地。只有Shell亲自动手改自己的工作目录,cd才可能生效。理解了这一点,后面很多“坑”就都通了。

1.2 成功总是静默的,确认位置要靠pwd

新手最容易产生的困惑是:敲了cd /tmp之后,终端好像什么都没发生,是不是没成功?这是Unix哲学里非常典型的一点——没有消息就是好消息。cd成功了不会打印任何提示,失败了才会把错误甩到你脸上。

想确认自己到底在哪儿,就要用pwd(print working directory)。我自己刚入行那会儿,总因为“cd没反应”而反复pwd,后来才养成了“切换完立刻pwd确认”的习惯。顺便说一句,pwd虽然看着简单,但它真的能帮你在迷路时快速定位:

$ pwd /home/kevin $ cd /var/log $ pwd /var/log

这里还藏着相对路径与绝对路径的核心区别:绝对路径从根目录/开始写,比如/var/log,无论你当前在哪都能定位;相对路径从当前目录开始写,比如从/home/kevin出发写log,指的就是/home/kevin/log。cd只是把你从“当前工位”移动到“目标工位”的移动指令,至于是按全城地图走还是按公司内部路线走,取决于你给的是绝对路径还是相对路径。

2. cd用法全家福:基础、进阶与隐藏开关

2.1 最常见的八种cd写法

很多人觉得cd没什么好记的,真用起来又会卡壳,就是因为没有这张“全家福”。先放一张速查表,适合贴在工位旁边,也适合收藏起来:

命令作用说明
cd 或 cd ~回当前用户的家目录交互环境下最常用
cd /absolute/path用绝对路径切换从根目录算起
cd relative/path用相对路径切换从当前目录算起
cd ..往上退一级可连写cd ../..
cd -回到上一个目录依赖变量$OLDPWD
cd "$VAR"用变量保存路径路径含空格时记得加引号
cd ~/xxx展开家目录注意~别放进引号里
cd /回到根目录服务器排障时常用

这里面最有价值的冷知识是cd -。它和方向无关,纯粹表示“上一次所在目录”。你正在/etc/nginx里改配置,转头想去/var/log/nginx看一眼日志再回去,一条cd -就搞定了,完全不需要重新敲长路径。bash在背后帮你维护了一个OLDPWD环境变量,cd -本质上是cd "$OLDPWD"的快捷方式。

2.2 容易被忽略的选项:-L、-P、-e

表格里的基础写法覆盖了99%的场景,剩下1%藏在选项里。cd看着简单,但它其实还带了几个选项,多数人一辈子可能都用不上一次,但一旦碰到符号链接就非常救命。-L是Logic,逻辑路径,也是默认行为;-P是Physical,物理路径,直接解析符号链接落到真实位置。

举个实际例子,很多系统的/bin本身是个符号链接,指向/usr/bin。假如你建一个链接:

ln -s /var/log /tmp/mylog cd /tmp/mylog pwd # 输出 /tmp/mylog,这是逻辑路径 cd -P /tmp/mylog pwd # 输出 /var/log,这是物理路径

日常在交互终端里,默认行为就够用了,你不需要关心自己到底是从哪个链接进去的。但在脚本里,如果你希望拿到“真实位置”而不要被一层层符号链接误导,cd -P就很关键。还有一个-e选项,它要求cd在目标目录不存在时返回一个非零状态码,非常适合在脚本里和各种失败处理组合使用。

2.3 三个环境变量:HOME、OLDPWD、PWD,以及CDPATH的秘密

聊完选项,另一个值得下功夫的维度是环境变量。前面提到了$HOME和$OLDPWD,它们其实都是环境变量。cd无参数时去的就是$HOME;cd -会用$OLDPWD;而$PWD则保存着当前目录,很多shell脚本靠它来拼接路径。这套机制非常好理解:cd命令不只是“移动”,它还在同步维护这些变量,让shell里的其他程序都能感知到你现在的位置。

还有一个平时很少有人主动用、但偶尔异常好使的变量叫CDPATH。它的作用和PATH很像,就是给cd命令添加“搜索目录列表”。默认情况下,你执行cd projects,shell只会在当前目录下找projects这个子目录。但如果设置了CDPATH,shell会按顺序去CDPATH里的每个目录找一遍:

export CDPATH=:~ # 冒号前留空,表示优先搜当前目录 cd projects # 如果当前目录没有projects,就会去 ~ 下找

注意,设置CDPATH之后,cd如果通过搜索找到了目录,会顺手把完整路径打印出来,告诉你去哪了。很多人第一次看到会以为出了什么错,其实这是正常的。CDPATH在脚本里要谨慎使用,因为它的“搜索优先级”可能和你预想的不一样,容易造成路径歧义。

3. 实战:把cd用出行云流水的效果

纸上谈兵差不多了,下面进入场景。我这里挑几个每天都在发生的场景,讲讲cd怎么用最顺手。

3.1 场景一:项目代码里的多层穿梭

很多人的习惯是一层层地cd进去:先cd ~/work,再cd company,再cd project,再cd src。这种习惯最大的问题是慢,而且每层都可能打错字,一旦在第二层迷路,还得靠pwd一步步确认。

我更推荐的做法是,直接写完整的目标路径,然后让Tab补全来兜底:

cd ~/work/company/project-a/src/components

你以为这是一整条路径,其实它可能只是你敲了cd ~/wor之后按了一次Tab补全出来的。Tab补全的价值不只在于少打字,更在于它顺便帮你验证了目录真实存在。你在哪个层级打错了一个字母,按Tab时shell都不会给你补全出来,这等于把“no such file or directory”的报错提前消灭在了输入阶段。

如果项目路径真的特别深,还可以在~/.bashrc里给常用目录设个变量:

export PROJECT=~/work/company/project-a/src/components cd "$PROJECT"

3.2 场景二:在两个目录之间反复横跳

对比两份配置文件、同步两个代码分支、来回查看日志和配置,大概是终端里最频繁的操作之一。很多人还在老老实实打全路径,其实cd -就是为这种场景准备的。

cd /etc/nginx cd /var/log/nginx cd - # 回到 /etc/nginx

你甚至可以组合使用:

cd - && ls # 回上一个目录并列出文件 cd - && cd - # 连续两次等于绕一圈回到原地

这个技巧看似简单,但真正养成习惯之后,效率提升非常明显。尤其是你在几十层的项目目录里调试,动不动就是“回刚才那个目录”,敲两个字符cd -远比重新补全一长串路径来得痛快。

3.3 场景三:把cd包装成自己的武器库

如果你每天要建一堆目录,或者在进入目录后总是想立刻看看里面有什么,可以在shell配置文件里加几个自定义函数:

# 创建目录并进入 mkcd() { mkdir -p "$1" && cd "$1" } # 进目录后自动列表 cd() { builtin cd "$@" && ls -F }

这里有个非常容易翻车的细节:当你自定义了同名cd函数之后,一定要在函数里用builtin cd而不是再写cd,否则就会变成自己调自己的无限递归,直接把shell卡死。我自己第一次写这个函数时就吃过这个亏,终端瞬间刷屏报错,最后只能强制关掉窗口。

除了手动函数,现在还有zoxide、autojump这类模糊跳转工具。它们会根据你的历史目录给目录打分,让你只要敲z pro就能跳到最常去的那个project目录。这类工具底层实际上也是在帮你算出目标路径,最后仍然调用cd进行切换。它们适合交互终端使用,但在脚本里我建议还是老老实实写明确路径,不要依赖这类智能猜测。

3.4 不同Shell的cd差异速查

cd在不同Shell里的基础行为一致,但细节上有一些差别,值得知道:

Shellcd的本质需要留意的差异
bash内建命令默认-L;支持CDPATH;tab补全很成熟
zsh内建命令开启AUTO_CD后,直接敲目录名也可进去
fish内建命令历史路径记忆更智能,基础写法一样
PowerShellSet-Location的别名用法类似,但很多bash习惯要改
cmd内部命令用反斜杠,不支持cd -这类写法

另外提一句,在zsh里开启AUTO_CD之后,你会进入一个“路径即命令”的爽快阶段,直接输入一个目录名就能切换,连cd两个字母都省了。不过这种用法在脚本里不推荐,因为会降低可读性。

4. 常见报错与排查实录

cd的报错大多不长,但每次出现都让人血压升高。先把最常见的几种讲透。

4.1 “No such file or directory”最常见的三种原因

这个报错估计是大家在cd上遇到最多的。原因通常在三个地方:第一,目录真的不存在。解决办法最简单,用ls看一圈,或者用Tab补全确认。第二,大小写写错了。Linux路径严格区分大小写,Documents和documents是两个完全不同的目录,这和Windows的习惯差别很大,很多人搬去Linux服务器后头几周都会被这事坑。第三,路径里包含空格或特殊字符,但没有加引号,导致shell把你的路径拆成了好几个参数,最终找到一个不存在的东西。

排查组合拳一般这样打:先pwd确认自己在哪,再ls看看相邻目录是什么样,最后用Tab补全把目标路径补出来。这套流程熟练之后,基本几秒钟就能定位问题。

4.2 路径里有空格、括号、中文怎么办

路径带空格是跨平台使用者的老朋友。在bash里,空格会被当成参数分隔符,所以直接cd My Documents一定会报错。正确的姿势有两种:加引号,或者用反斜杠转义:

cd "My Documents" cd My\ Documents

两种写法效果一样。中文目录也是一样处理,用引号包起来或者靠Tab补全。还有一个非常容易踩的坑是~号:在bash里,~只有在不被引号包裹的时候才会被展开成家目录。所以cd "~/Downloads"实际上找的是一个名字叫~的目录,大概率会报错;正确的是cd ~/Downloads或者cd "$HOME/Downloads"。

在Windows的Git Bash或者WSL里还要注意盘符路径的写法。你从Windows习惯里带来的C:\Users\xxx在Linux环境里基本是不可用的,通常要改写成/c/Users/xxx或者用Windows的C:/Users/xxx风格,这个转换经常让新手崩溃。

4.3 PowerShell里cd突然报“Set-Location无法识别”

热搜里有这条,很多人在Windows下用PowerShell,突然有一天敲cd就报错:

cd : 无法将“Set-Location”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

这里的cd本质是Set-Location的别名,报错说明你当前这个PowerShell会话压根找不到Set-Location命令。最常见的原因是Microsoft.PowerShell.Management这个模块没有正常加载,或者Profile脚本里有人改过别名/函数。排查步骤我按顺序列一遍:

Get-Command Set-Location # 看这个命令是否还存在 Get-Alias cd # 看cd别名指向哪里 Get-ChildItem Function:cd # 看是否有个同名函数抢占了 Import-Module Microsoft.PowerShell.Management -Force # 强制导入模块 Set-Alias cd Set-Location # 如果只是别名被删,重建即可

很多时候直接重启一个PowerShell窗口就能恢复,因为重新加载的会话会重新初始化模块。如果重启后还是报错,那要怀疑Profile脚本了,用notepad $PROFILE打开排查,看看里面是不是写了Remove-Item Alias:cd之类的“危险操作”。

4.4 脚本里的cd:失败后绝不要硬着头皮继续跑

这是我认为最值得盯紧的一条。交互终端里cd失败,你顶多骂一句再敲一次;脚本里cd失败,后面的命令会在错误目录里继续执行,轻则部署失败,重则删错东西。

看这个危险的例子:

cd "$BUILD_DIR" rm -rf ./*

如果BUILD_DIR在某个环境下是空字符串,cd "$BUILD_DIR"会报错,但脚本默认不会因为这一条失败而停下来,rm -rf ./*照样执行,直接就在当前目录开删。如果你当时正好在家目录,那家目录就没了;如果是无引号写法cd $BUILD_DIR,空变量会被删除,等于cd后面没有参数,shell直接回到家目录再开删。真实运维事故里,这种“rm -rf + 空的构建目录变量”的组合炸掉过不少人的服务器和本地环境。

正确姿势是加保护:

cd "$BUILD_DIR" || { echo "无法进入 $BUILD_DIR"; exit 1; }

更保险一点,先用参数展开拒绝空变量:

BUILD_DIR="${BUILD_DIR:?构建目录变量为空}" cd "$BUILD_DIR" || exit 1

另外也提醒一下,很多人以为脚本开头写了set -e就能万事大吉,其实set -e在cd出现在if、while这类复合命令的判断条件里时是不生效的。所以别把set -e当挡箭牌,老老实实给关键cd加失败处理才是正道。

5. 写在最后:几个翻了车才记住的细节

写到这里,cd能讲的基本都讲完了。最后分享几条我自己在实际工作里的体会,算不上真理,但确实是拿教训换来的经验。

第一条,交互终端里,请把Tab补全当成cd的好朋友。我见过太多人一个字一个字敲完整路径,结果敲到一半发现自己已经迷路。Tab补全不仅快,而且它每一次成功补全都在帮你确认路径真实存在,相当于提前排除了一半的报错。

第二条,写脚本时永远假设cd会失败。不管脚本看起来多简单,cd到目标目录后要随手上锁:要么紧跟|| exit 1,要么用变量展开检查空值。这把锁看着烦人,但真能救你的家目录一回。

第三条,cd -这个习惯,值得专门花一个礼拜刻意练习。我说的是那种“切过去看一眼再切回来”的场景,别傻乎乎地敲第二次长路径。一旦你尝到cd -的甜头,就很难回去了。

我最早接触命令行时,总觉得cd太简单,不值得研究。后来在脚本里被rm -rf坑过一次,在服务器上被符号链接绕晕过一次,才明白越是基础的命令,越值得把它每个角落摸透。cd只有两个字母,但这两个字母决定了你接下来所有命令会在哪片土地上执行——把这片土地摸熟,比多背一堆花哨命令都管用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 5:14:04

UPI支付接口协议逆向实战:从状态机到超时重试幂等设计

早些年一提"逆向协议",圈子里默认聊的是破解、抓包、绕过验证这些偏门活儿。我在支付中台干了几年之后,对这种刻板印象越来越不认同——在真实的生产环境里,协议逆向是一件极其朴素的事:你依赖的接口文档没有写清楚边界…

作者头像 李华
网站建设 2026/9/28 5:13:53

CSS布局与视觉样式实战:Flex、Grid、渐变阴影与3D变换技巧

CSS布局与视觉样式,这两个词看着简单,实际用起来能把人逼疯。我最早写页面的时候,左右两栏布局全靠float加margin调来调去,调一个像素可能要刷新半天,后来Flex和Grid出现,效率才真正提上来。但如果你接触过…

作者头像 李华
网站建设 2026/9/28 5:13:40

熬夜的微观真相:成年人每一次熬夜,都在透支体内NAD+储备

熬夜的微观真相:成年人每一次熬夜,都在透支体内NAD储备 几乎所有成年人都知道熬夜伤身,但多数人只感知到表层的疲惫、暗沉、精神差,却不知道熬夜对身体的微观损耗到底发生在哪里。人体夜间是细胞修复、代谢更新、物质合成的黄金周…

作者头像 李华
网站建设 2026/9/28 5:13:38

基于SSM框架的个性化影片推荐系统:协同过滤算法实战

简介:面向Java方向毕业设计及SSM框架初学者,这份个性化影片推荐系统资料包提供从项目源码到论文答辩的全套内容。系统基于SSM(SpringSpringMVCMyBatis)架构,结合JSP前端与MySQL 5.7数据库,涵盖用户管理、电…

作者头像 李华
网站建设 2026/9/28 5:13:10

电子信息专业嵌入式与芯片方向四年学习规划

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 5:10:14

Python知识库问答seq2seq模型实战:从FAQ表到对话系统

简介:这份资源面向具备一定Python与深度学习基础的开发者,提供一套基于知识库的问答Seq2Seq模型完整代码实现,帮助读者理解从数据预处理到模型训练、评估与部署的全流程。压缩包共21个文件,约3.39MB,以7个py脚本为核心…

作者头像 李华