当前位置:首页>Linux>每天学一个Linux命令系列(2):cd - 一键回到上一级?cd还有这种操作

每天学一个Linux命令系列(2):cd - 一键回到上一级?cd还有这种操作

  • 2026-09-02 16:40:19
每天学一个Linux命令系列(2):cd - 一键回到上一级?cd还有这种操作
运
运维少年 · 科技观察

这个命令是干啥的

cd,change directory,切换当前工作目录。Unix/Linux 系统里最基础也是最常用的命令之一。

在我刚开始用 Linux 的时候,cd 就是从一个目录跳到另一个目录。cd /home、cd /var/log、cd /,没了。后来我慢慢发现,cd 其实藏着不少偷懒技巧。尤其是每天在不同路径之间来回切换的运维场景,用好 cd 能省下大把敲键盘的时间。

比如你在 /usr/local/nginx/conf/vhosts/ 这种深目录里干活,想去 /etc/nginx/sites-enabled/ 看一眼配置,再切回来。要是每次都手打完整路径,一天下来手指头都酸了。

基本用法(3分钟上手)

最基本的就不多说了:

# 进入指定目录
cd /var/log

# 回到家目录
cd

# 进入上一级目录
cd ..

# 进入上两级目录
cd ../..

但是大多数人不知道的小技巧来了。

回到上一次目录:

# 切到日志目录
cd /var/log/nginx

# 切回去刚才的目录
cd -

cd - 这个我每天用几十次。特别是在多个深度目录之间来回切换的时候,比 cd ../../.. 快太多了。

# 打印当前目录再切换
cd - && pwd

# cd - 本身就会打印路径,其实不需要额外pwd
cd -

cd - 执行的时候控制台会打印出路径,看着就很安心。

回到家目录的变体:

# 直接回家
cd ~

# 回到root用户的家目录
cd ~root

# 回去指定用户的家目录
cd ~zhangsan

cd ~user 这个在管理多用户机器时非常有用。看其他用户目录下的文件,不用先 ls /home/zhangsan 再看路径了。

用绝对路径和相对路径的混合:

# 当前路径 /usr/local/nginx/conf/
cd /etc/nginx/conf.d/

# 刚才的位置还在 $OLDPWD 里存着
echo $OLDPWD

$OLDPWD 是个环境变量,cd 进去一个目录后,系统自动把上一个目录存进去了。cd - 底层就是在读这个变量。

进阶骚操作

pushd / popd / dirs 目录栈:

这个是我后来才搞明白的,但一用就离不开了。

# 入栈,把当前目录压入栈中
pushd /etc/nginx

# 入栈另一个目录
pushd /var/log/nginx

# 看看栈里有什么
dirs

# 出栈,回到上一个压栈的目录
popd

目录栈可以压多个,用 pushd 压入,popd 弹出。适合来回在几个目录之间跳跃的场景。

# 显示栈里所有目录,每个一行
dirs -p

# 清空目录栈
dirs -c

带编号的切换:

# 切换到栈里的第三个目录(从0开始数)
pushd +2

# 切换到栈里最后一个
pushd -0

栈操作看起来复杂,但实际用起来顺手得很。后面实战部分会说具体用法。

cd 到符号链接的物理路径:

# 进入软链接目录后,看到的是链接指向的真实路径
cd -P /etc/alternatives

# 如果只想看物理路径,不加-P就留在软链接里
cd -L /etc/alternatives

这个 -P 和 -L 区别在 pwd 那篇文章里会细讲。总之记住:-P 走物理路径,-L 走逻辑路径。

autojump - 懒人必备:

# 如果系统装了autojump
j log

# 直接跳到最常访问的包含log的目录
# 不用记完整路径,autojump用权重算法记住你的习惯

autojump 是个第三方工具,装好之后你用 cd 去过的目录都会被记录下来。以后只要 j 关键字 就能跳过去。频率越高的目录权重越大,跳得越准。

类似的还有 z 和 fasd,挑一个习惯就行。

CDPATH 环境变量:

# 设置CDPATH
export CDPATH=:/etc:/var:/usr/local

# 然后直接 cd nginx,不用写完整路径
cd nginx

不加 CDPATH 的话,cd nginx 只在当前目录下找子目录 nginx。加了之后会在 CDPATH 列表里依次查找。适合经常跑 /etc、/var 等固定位置干活的人。

避坑指南

坑1:cd 到一个不存在的目录没提示?

# 这个不会报错
cd /tmp/doesnotexist 2>/dev/null

# 但目录不存在,pwd发现根本没跳转
pwd

如果你把 cd 写在脚本里,最好检查返回码:

cd /some/important/path || { echo "目录不存在"; exit 1; }

坑2:Cdpath 设了反而让你迷路

# 假设 CDPATH 里有 /etc
# 当前目录下也有一个 nginx 子目录
# 你 cd nginx 跳到了哪个?
# 答案是 CDPATH 里匹配到的第一个

CDPATH 是个双刃剑。设了之后 cd 行为变了,有些脚本可能会有预期之外的表现。我一般只在交互式 shell 里设置,不会写到 /etc/profile 里影响全局。

坑3:cd - 在脚本里不好使

#!/bin/bash
cd /var/log
# 干点事...
cd -

脚本里 cd - 的行为可能会被你执行时的目录结构影响。脚本里最好用绝对路径,或者用 subshell 来处理:

#!/bin/bash
(
  cd /var/log
  # 这里随便cd,外面的目录不受影响
)
# 这里还在原来的目录

subshell 里的 cd 不会影响父 shell,是个好习惯。

坑4:cd 到文件名有空格的地方

# 目录名是 "My Documents"
cd My Documents
# 这实际上 cd 了两次:先进 My,再进 Documents

# 正确的做法
cd "My Documents"
cd My\ Documents

实战场景(重点!结合真实运维场景)

场景一:排查多个服务配置文件

有一次线上 nginx 报错 502,我需要同时看 nginx 配置和 php-fpm 配置,还有后端服务的日志。

# 先用pushd把几个目录都压进去
pushd /etc/nginx/conf.d
pushd /etc/php-fpm.d
pushd /var/log/php-fpm

# 用popd来回切换
# 先到nginx配置
popd
# 改完
pushd /etc/nginx/conf.d

# 再到php日志
popd +1

来回切不用打长路径,效率高了很多。排查完事了一个 dirs -c 清空收工。

场景二:深层次项目目录的快速穿梭

项目目录结构:/data/projects/myapp/v2.3/src/main/java/com/company/module/controller/

经常要在 controller、service、dao 三个包之间切:

# 不是直接cd完整路径,而是用CDPATH
export CDPATH=.:/data/projects/myapp/v2.3/src/main/java/com/company/module

# 然后直接 cd controller、cd service、cd dao

配合 tab 补全,效率起飞。

场景三:自动化部署脚本中的目录管理

写部署脚本时,目录切换是最容易出问题的地方:

#!/bin/bash
APP_DIR=/data/app/myapp
BACKUP_DIR=/data/backup/$(date +%Y%m%d)

# 先切到备份目录
mkdir -p "$BACKUP_DIR" && cd "$BACKUP_DIR"
# 备份当前版本
cp -r "$APP_DIR" ./myapp_backup

# 切回app目录
cd "$APP_DIR"
# 在这里执行git pull或者解压新包

用 $() 定个变量,路径写清楚,比硬编码强多了。不然改个路径名,脚本全废。

场景四:用 cd 配合 find 批量操作

# 先到目标目录
cd /data/old_logs

# 批量处理文件
for f in *.log.gz; do
  gunzip "$f"
done

# 搞完回到原来的位置
cd -

虽然用绝对路径也能写循环,但先 cd 过去再处理就省得每个命令前都带路径了。

今日作业

打开终端,试试以下步骤:
1. 用 pushd 压入 3 个不同的目录
2. 用 dirs -v 查看栈里的编号
3. 用 pushd +1 切换到第二个目录
4. 再用 popd 逐个弹出

然后说说看:dirs -v 输出里的编号从 0 开始还是从 1 开始?

E N D

运维少年 · 科技观察

最新文章

随机文章