Linux cd命令从入门到精通:路径切换、磁盘管理与脚本避坑指南
1. 为什么要把cd归到磁盘管理里看到这个标题估计不少人心里犯嘀咕cd不就是切换目录吗跟磁盘管理八竿子打不着吧。其实把cd放进磁盘管理这个分类仔细想想是有道理的。磁盘管理这一层说白了就是跟存储、分区、挂载、目录打交道。你在Linux上插一块新硬盘要分区、要格式化、要挂载到某个目录挂载完之后呢你得cd到挂载点里去看看文件有没有正常写入。你要清理磁盘空间得先一个目录一个目录地cd进去用du、df看看哪里占的磁盘最多。磁盘管理的起点永远是先搞清楚自己在哪个目录、能去哪儿。cd命令的熟练程度直接决定了你在磁盘管理和日常命令行操作里的效率。另外还有一个冷知识cd是shell内建命令压根就不是一个独立的可执行文件。你运行which cd大概率什么都查不到因为它直接由bash、zsh这样的shell解释器处理的不走PATH搜索那套流程。这一点和ls、cp这类外部命令有明显区别。明白了这一点你就能理解为什么cd在某些特殊场景下行为和普通命令不太一样。对于刚接触Linux的新手cd是你敲进去的第二个命令——第一个通常是ls。对于干了两三年的运维和开发cd早就敲成了肌肉记忆一天可能要按几百次。但这篇文章想说的是:即便是这么基础的一个命令,里面依然有不少坑、不少技巧,值得摊开来讲透。2. 先搞清楚绝对路径和相对路径cd 才不算白学2.1 从当前目录出发的“相对路径”与从根目录出发的“绝对路径”很多人cd用不利索问题不在cd本身而是没搞懂路径的两种写法。这个概念如果没吃透后面什么符号链接、脚本编写、定时任务全都会踩坑。绝对路径就是从根目录/开始写一条路走到底。比如你要进/var/log这个目录就是cd /var/log这条命令不管你在哪个位置都能直接到达目的地。绝对路径的好处是确定性强、可重复坏处是比较长敲起来累。相对路径就是从当前位置出发去往目标目录的路线。比如你现在在/var/log里想进/var/log/nginx就可以直接cd nginx不需要写一大串绝对路径。再比如你现在在/var/log/nginx里想回到/var/log那就可以cd ..这里的..代表上一级目录。相对路径的好处是短、灵活坏处是你一旦搞不清自己当前的位置就很容易跑偏。我见过不少新手在这个地方栽跟头明明想进/usr/local/nginx结果因为当前目录是/usr/local就输入了cd nginx/x — 其实这样的写法从当前路径的下一级nginx的子目录x去找如果/usr/local下没有nginx这个目录自然就报错了。两个常见错误习惯得改掉依赖pwd确认当前位置后再写相对路径而不是凭记忆瞎猜。不要把绝对路径和相对路径混着写比如cd /var/log/../tmp这种写法虽然技术上成立但可读性极差纯粹给自己找麻烦。2.2 特殊目录符号的完整清单路径写法的核心是掌握下面这几个特殊符号。我直接整理成一张表日常使用频率从高到低排符号含义示例说明.当前目录cd ./nginx单点几乎可以省略偶尔用于脚本中强调当前位置..上一级目录cd ..两点回到上一级可以叠加比如cd ../..向上两级-上一个所在目录cd -在两个目录之间来回横跳极其好用~当前用户的家目录cd ~等价于直接敲cd回车~user指定用户的家目录cd ~mysql需要该用户存在否则会报错/根目录cd /所有路径的起点这几个符号里我觉得值得单独拎出来重点说的是cd -。它记住的是你上一次所在的目录利用的是shell里的环境变量OLDPWD。这个功能在什么场景下最爽比如你在写配置文件先cd到/etc/nginx去改配置然后需要去/var/log/nginx看日志文件看完了又想切回去继续改配置。这时候你只需要敲cd -连目录名都不用输入直接弹回上一个工作目录。来回切几次你会真切感觉到这个设计的巧妙。还可以告诉你一个小细节cd -执行时会自动把目标路径打印在终端上。这方便你确认自己到底切到了哪儿也方便你在脚本里捕获这个值。如果你不想看到这行输出可以用cd $OLDPWD代替效果一样但不打印。3. cd 命令的完整用法与返回机制3.1 cd 的完整语法与三种调用方式正式地讲cd命令的语法范例如下cd [-L|[-P [-e]] [-]] [dir]先别被这一串吓到平时你基本用不到这么复杂的组合。最常用的其实只有三种调用方式第一种直接不带参数cd不带任何参数时cd会把当前目录切换到当前用户的家目录。如果你用root登录就回到/root用普通用户就回到/home/用户名。这是最快捷的“回血”方式比敲cd ~还省一个字符。第二种带一个路径参数cd /some/path这个不用多说目标路径可以是绝对路径也可以是相对路径。需要提醒的是路径里不要混入空格如果确实有空格必须用引号包起来。比如进入名为My Documents的目录得写成cd My Documents或者cd My\ Documents直接裸敲空格会被当成两个参数。第三种带特殊符号参数cd - # 回到上一个目录 cd ~ # 回到当前用户家目录 cd ~user # 回到指定用户的家目录 cd .. # 回到上一级目录这三种调用方式覆盖了日常百分之九十九以上的使用场景。3.2 CDPATH 环境变量与逻辑路径、物理路径的坑关于cd命令有两个比较隐蔽的知识点网上很多教程不会提但实际工作中踩到会困惑半天。第一个是CDPATH环境变量。它类似于PATH变量但作用是给cd命令提供一个搜索路径列表。当你执行cd abc而当前目录下没有abc这个子目录时shell会按CDPATH里定义的一组目录逐一查找看哪个目录下面有abc。如果你设置了export CDPATH:/etc那么你在任何目录下执行cd nginxshell都会先看看当前目录有没有nginx如果没有就去/etc下找。这个变量在某些环境下会被系统预设导致出现“灵异现象”——明明当前目录没有这个子目录cd却成功切到了别处。遇到这种情况可以运行echo $CDPATH检查一下不需要的话用unset CDPATH取消。第二个是符号链接的逻辑路径和物理路径问题。假设/tmp/data是指向/mnt/storage/2024data的符号链接你执行cd /tmp/data此时你人已经在/mnt/storage/2024data里了但shell里的PWD变量记录的仍然是/tmp/data这个逻辑路径。直接运行pwd显示的是/tmp/data运行pwd -P才会显示物理路径/mnt/storage/2024data。这个问题在写脚本的时候特别坑。因为有些脚本靠pwd获取当前目录然后基于这个路径去引用相对文件。如果你通过符号链接进去的拿到的是逻辑路径一旦脚本把路径当作真实路径去拼接可能就找错文件了。解决办法是在脚本需要精确路径时用pwd -P取物理路径。另外cd -P /tmp/data可以直接把当前目录切到物理路径PWD变量也直接记录真实路径。4. 实操场景从磁盘挂载到日志排查cd 怎么用得飞起4.1 挂载新磁盘后的目录切换操作流说回磁盘管理这个主题。假设你给服务器加了一块新硬盘按常规流程走一遍你会发现cd在里面扮演的角色远比想象中多。第一步查看系统是否识别到新磁盘输入lsblk或者fdisk -l确认新磁盘的设备名比如/dev/sdb。这是纯粹的磁盘操作还没用到cd。第二步分区和格式化。前面这些都在系统层面操作不需要进入特定目录。第三步创建挂载点并挂载。这里就要用到cd了。比如你准备把新磁盘挂到/data目录得先确认/data存在。不存在就创建ls -ld /data如果提示不存在继续sudo mkdir -p /data然后挂载sudo mount /dev/sdb1 /data挂载完成接下来要验证。这时候cd的用武之地就来了cd /data ls -la你会发现在/和/data这两个目录下看到的lostfound目录不一样——挂载ext4文件系统的磁盘根目录天然有个lostfound目录。如果你cd进一个刚挂载的空盘却看不到lostfound那说明你挂载可能失败了或者误挂到了别的地方。这个细节在排查磁盘挂载问题时很实用。然后你可以cd进/data的子目录做读写测试mkdir /data/test cd /data/test touch hello.txt ls -l整个流程走下来cd看似只是“进入目录”这一个动作但实际上它是验证挂载结果、确认文件系统可读写的关键操作。如果没有cd进去看你都不知道挂载是否成功。4.2 日志目录、大文件目录切换的日常习惯再举一个运维日常里非常高频的场景排查日志和清理磁盘空间。登录服务器第一件事通常就是进日志目录。大部分人习惯直接敲cd /var/log然后ls看有哪些日志。但高手会稍微加快一下效率比如知道nginx日志在/var/log/nginx下就直接一条命令到位cd /var/log/nginx ls -lh access.log error.log这里用把cd和ls串起来一条命令完成“进入目录查看文件”两个动作。表示只有当前一条命令执行成功才继续执行后一条。这种串法是cd命令在脚本和日常操作里最常见的组合用法之一。但是这里有一个习惯必须养成写脚本时尽量不要依赖cd这是我在生产环境里踩过坑后得出的血泪教训。原因有三脚本里cd之后如果后续某条命令执行失败脚本会因为当前目录已经改变而继续在错误的位置运行结果不可预测。如果脚本被并发执行或者被别的地方调用cd会改变全局的当前目录状态可能影响其他逻辑。更稳妥的做法是脚本内部统一使用绝对路径或者用子shell把cd包起来(cd /var/log/nginx grep ERROR access.log)这样cd只在子shell内生效不影响外部脚本的当前目录。日常在终端操作时还有一个实用习惯在磁盘告警时要快速定位哪个目录占用最大可以先cd到根目录或挂载点然后一层层找cd / du -h --max-depth1 . | sort -hr | head -20这里du命令会输出每个一级子目录的占用大小看到哪个目录占用大就cd进去再执行同样的命令。这种“cd du sort”的组合是定位磁盘占用的标准操作流程。如果你熟练掌握cd的各种用法这个排查过程会非常顺滑。另外批量处理多个目录时不需要反复cd。很多人习惯进入目录一处理完就cd回上一级再进入下一个目录。其实完全可以在一个目录里用绝对路径操作所有目标或者用find命令一次性搞定。比如要查找所有超过1GB的大文件find / -type f -size 1G -exec ls -lh {} \; 2/dev/nullfind的-exec里面会自己处理不需要你cd来cd去。命令行的哲学是用工具组合替代无谓的目录跳转效率高得多。4.3 用 cd 组合其他命令的高频实战片段除了上面说的连接我再分享几个高频的cd组合片段都是生产环境下实测好用的。快速回到项目的某个固定目录。不少开发者的做法是给常用目录设置别名在~/.bashrc里加一行alias projcd /home/user/work/my-project/src以后敲proj就直达项目目录。类似的还可以给日志目录、配置目录设置别名。别小看这个习惯长期积累下来能省大量时间。临时需要一个目录保存文件可以这样mkdir -p /tmp/backup_$(date %F) cd $_这里$_是上一个命令的最后一个参数也就是刚创建的目录路径。cd $_可以直接切进去。这个技巧比反复用上下箭头翻历史命令要快得多。在两个相关联的目录之间来回切换比如配置文件目录和工作目录用cd -的技巧我在前面说过。如果觉得只记一个“上一个目录”不够用还可以借助pushd和popd来实现多目录栈管理pushd /etc/nginx pushd /var/log/nginx pushd /usr/local/src dirspushd会把当前目录压入目录栈然后切换到新目录。用popd可以按逆序弹栈并切换回去。dirs列出当前栈内容。这个组合在需要同时在多个目录之间穿梭时比反复cd和cd -更高效。5. 常见问题排查与避坑实战5.1 报错速查表日常工作里cd命令最常见的报错无非下面几种我直接把原因和解决办法整理成表报错信息原因解决办法bash: cd: xxx: No such file or directory目标目录不存在或者相对路径写错用ls确认路径拼写检查当前位置bash: cd: xxx: Permission denied当前用户无权限进入该目录检查目录权限必要时sudo切换或使用有权限的用户bash: cd: xxx: Not a directory目标路径不是目录而是一个普通文件用ls -ld确认类型别拿文件当目录进cd: HOME not set用户家目录环境变量未定义手动set HOME/home/用户名多见于非正常登录会话bash: cd: 参数太多路径中包含未转义的空格用引号包住路径cd My Documents5.2 用 sudo 切换用户后目录问题的迷思还有一个很有意思的场景很多人会困惑为什么我用su切换到root后当前目录还是原来那个目录先说su和su -的区别。不带-的su会切换到目标用户但保留当前目录、环境变量等一系列状态。带-的su会开启一个全新的登录会话类似于该用户重新登录系统目录默认回到该用户的家目录。举个例子你是一个普通用户当前在/home/user/data目录下执行sudo su后你依然停留在/home/user/data而不是root的家目录/root。如果你执行sudo su -那么就会跳到/root。理解这个区别很重要。有些情况下你确实需要保留当前目录比如在一个临时目录里处理文件切换root后想继续在这个目录操作。这时候用不带-的su就正好。另一些情况下你希望隔离环境获得干净的root登录环境用su -更合适。与这个类似的是sudo执行时的目录问题。你运行sudo ls因为sudo默认会保留当前工作目录所以执行结果和你直接ls差不多。但sudo -i会模拟一个root的完整登录环境目录会切到/root。5.3 脚本中 cd 失败时如何防止错误扩散写shell脚本时cd命令有个隐蔽的“坑”——它如果失败了默认不会终止脚本执行。比如下面这段脚本#!/bin/bash cd /nonexistent-directory rm -rf *如果/nonexistent-directory不存在cd会失败但脚本不会停下来而是继续执行rm -rf *。此时脚本仍然停留在调用者原来的目录删除操作就会作用于调用者目录下的所有文件。这个后果有多严重不用我多说。完善的写法有几种用set -e任何一个命令返回非零状态就立即退出脚本#!/bin/bash set -e cd /nonexistent-directory或者显式判断cd是否成功#!/bin/bash if cd /nonexistent-directory; then rm -rf * else echo 无此目录停止操作 2 exit 1 fi或者用||把失败操作挂在后面最简单的防呆写法cd /some/dir || exit 1这种习惯一定要养成。我在带团队的时候要求所有脚本里的cd都必须带错误处理。原因就是这类问题在测试环境可能永远不暴露一旦上了生产遇到目录不存在的一次意外就可能引发数据浩劫。5.4 Tab 补全和引号使用的细节最后说几个谈不上是“问题”但能显著提升效率的细节。第一个是Tab键补全。Linux终端里按Tab键可以自动补全路径。但你得知道两个层次按一次Tab如果匹配唯一自动补全完整路径如果匹配多个再按一次Tab会列出所有可能项。比如你输入cd /var/l按Tab系统会尝试补全成/var/log如果/var下面有其他以l开头的目录第一次按键没反应或只补全一部分按两下就列出所有候选。这个操作在长目录名和带版本号的目录之间切换时价值巨大。第二个是目录名里有空格的处理。Linux支持带空格的目录名但这在命令行操作里非常容易出错。我的建议是自己创建目录时尽量别用空格用下划线或中划线代替。如果确实碰到了别人创建的带空格目录用Tab补全最省心——终端会自动帮你转义成带反斜杠的格式不需要自己手动加引号。第三个是关于cd的“隐形输出”问题。在shell脚本里如果你把cd放在变量替换或者命令替换中要特别注意是否会把输出带入其他命令。比如cur_dir$(cd /some/dir pwd)这个写法的意思是先切换到目标目录然后把pwd的结果赋值给cur_dir。这里cd后面的路径如果错了后面的pwd不会执行cur_dir就为空。这种写法本身没问题但要求你对每一步的返回状态有清晰的认识。6. 回归命令行本质把 cd 变成你的肌肉记忆写到这里我想聊一点个人体会。接触Linux这些年见过不少刚入行的同事把注意力放在各种花哨工具上比如各种终端模拟器的标签页、远程管理的面板、图形化的文件管理器却连最基本的cd和相对路径都掌握得不扎实。等真正要写脚本、排查线上问题的时候才发现基本功薄弱带来的掣肘有多大。cd命令再简单它也是你和整个Linux文件系统打招呼的方式。每一天的运维工作从cd进入第一个目录开始每一次的故障排查也要靠cd绕到关键路径下面才能定位问题。这个命令熟练到什么程度才算过关我的标准很简单闭着眼睛知道自己在哪个目录知道去哪儿要多久知道用相对路径还是绝对路径更顺手遇到符号链接能立刻反应过来是不是隐藏了真实路径。也有个值得坚持的日常习惯就是每次命令行要进入某个目录前先花零点几秒想一下我是直接敲绝对路径快还是先cd再一步一层进更快虽然这听起来有点较真但长年累月省下的时间和减少的错误是客观的。尤其是配合Tab补全和CDPATH之后整个操作节奏会顺滑很多。最后再分享一个小技巧如果你经常要在多个深度路径之间切换试着给这些路径在~/.bashrc里定义变量。比如export NGX_LOG/var/log/nginx export NGX_CONF/etc/nginx之后你就能这样用cd $NGX_LOG cd $NGX_CONF变量名的语义清晰比直接敲一长串路径好记忆也比alias更灵活——因为变量还能用在其他命令里比如tail -f $NGX_LOG/error.log。这是我个人最常用的实践之一建议你试试看。