切换 shell 的当前工作目录,并分清逻辑路径与符号链接解析后的物理路径。
cd 是 shell 内建命令,不是 /usr/bin 下的独立程序。macOS 从 Catalina 起默认登录 shell 是 zsh,/bin/bash 仍是 3.2 版;两者都支持 cd、cd -、cd -P、pushd/popd,但补全、CDPATH 和部分选项细节不同。不带参数执行 cd 会回到 $HOME,cd - 回到 $OLDPWD 并打印路径。
cd -L 是默认行为,按逻辑路径处理 ..,保留你输入时的符号链接路径;cd -P 先解析符号链接再切换。脚本里如果后续要用 pwd -P 或比较真实路径,应显式使用 cd -P。cd 需要路径上每一级目录都有执行(x)权限,只有读权限进不去。
cd 是 shell 内建,所以没有 GNU/BSD 可执行文件之分;差异主要来自 zsh 与 bash。脚本应假设 POSIX 行为,不要依赖 zsh 特有的目录替换语法;需要兼容时用 cd -- "$dir" 并给变量加引号。
# 回到主目录,不依赖 $HOME 是否为空
% cd ~
# 回到上一个目录,并显示切换后的位置
% cd -
# 解析符号链接后进入,后续 pwd -P 得到真实路径
% cd -P /tmp
# 目录名含空格或前导 - 时,用 -- 结束选项并加引号
% cd -- "$HOME/My Projects"
# 在脚本中进入目录,变量为空则立即报错退出,避免误入根目录
% cd "${TARGET_DIR:?TARGET_DIR 未设置}"
# 用目录栈临时切换多个位置
% pushd ~/Projects/app && popd
cd $DIR 在 DIR 为空时会回到主目录而不是报错,后续的 rm、cp 就可能作用在错误位置。脚本统一写 cd "${DIR:?}",并先确认 [[ -d $DIR ]]。$(...) 里执行 cd 不会改变父 shell 的目录。需要影响外部时用 source 执行脚本,或直接在主 shell 操作。cd /tmp/link 后 pwd 显示 /tmp/link,pwd -P 显示链接目标。排查“为什么文件写到了别处”时先看 pwd -P。Permission denied 通常是缺少执行位,而不是缺少读权限。用 ls -ld 目录 检查,chmod +x 只加在需要的目录上。CDPATH 会让 cd foo 跳到意外位置,脚本应 unset CDPATH 或使用绝对路径。pwd 可能给出旧路径,pwd -P 会报错;用 cd ~ 离开。合上页面,先回答,再展开对照。
cd -P /tmp/link 与 cd /tmp/link 后,pwd 和 pwd -P 分别可能显示什么?cd "$DIR" 在变量为空时很危险?应怎样写?bash -c 'cd /tmp' 里切换目录,为什么执行完后当前 shell 还在原目录?cd 保留逻辑路径,pwd 显示 /tmp/link;cd -P 解析链接,pwd -P 显示真实目标路径。cd 回到主目录,后续相对路径操作全部错位;改写为 cd "${DIR:?}"。bash -c 启动的是子进程,子进程的当前目录变化不会传回父 shell。
小程序版
微信扫码,随时查命令