readlink不加参数仅输出软链接中存储的原始路径字符串(含相对路径或../),-e要求所有路径组件存在且最终目标必须真实存在才返回绝对路径,-f则强制解析为绝对路径但允许最终目标缺失。

直接用 readlink 就行,但不同场景下参数选错会导致路径不完整、相对路径残留,甚至静默失败。
只看链接“写了什么”:用 readlink 不加参数
它输出符号链接文件里**实际存储的字符串路径**,可能是相对路径,也可能带层级跳转(比如 ../bin/python3),不解析、不补全、不验证存在性。
- 适合快速确认链接内容是否符合预期(比如检查是否误写成
../../wrong/path) - 脚本里慎用——
$(readlink mylink)返回的路径无法直接cd或stat,容易报No such file or directory - 如果链接指向另一个符号链接,它只展开第一层,不会递归
要绝对路径且确保真实存在:优先用 readlink -e
-e 会递归解析所有中间符号链接,并要求**每一段路径都必须存在**,否则命令失败(退出码非 0),输出为空。
- 适合校验环境完整性,比如启动服务前检查配置软链是否有效:
if [ -z "$(readlink -e /etc/myapp/config)" ]; then echo "config link broken"; exit 1; fi - 和
-f的关键区别在于容错:若目标文件被删了,-f仍返回路径(可能误导),-e直接失败,更安全 - 注意:它不处理末尾不存在的文件名(比如
mylink -> /tmp/missing.txt),只要/tmp存在就通过;但若/tmp本身是坏链接,就会失败
需要绝对路径但允许目标缺失:用 readlink -f
-f 是最常用也最容易踩坑的选项——它强制拼出绝对路径,把所有中间链接都展开,但**不管最终目标是否存在**。
- 适合构建路径字符串,比如日志归档脚本中生成归档目录:
ARCHIVE_DIR="$(dirname "$(readlink -f /var/log/app/current.log)")/archive" - 风险点:如果最终目标被删了,
readlink -f仍返回一个看似合理的路径,后续cp或cat会报错,错误源头难追溯 - 它对路径中不存在的组件(如
/a/b/c中b不存在)会报错退出,这点和-e一致;区别只在最后一级文件/目录是否存在
替代方案:realpath 和 ls -l 的适用边界
realpath 行为接近 readlink -f,但更强调“标准化路径”,会自动折叠 ./、../,且默认要求所有路径段存在(类似 -e);ls -l 只用于人工查看,输出含 -> 的那一行,不能直接用于脚本提取。
-
realpath在部分旧系统(如 CentOS 6)可能未预装,而readlink几乎全平台可用 -
ls -l mylink输出形如lrwxrwxrwx 1 user user 12 Jun 10 10:00 mylink -> /opt/target,但要用awk或sed提取箭头后内容,不如readlink干净 - 真正容易被忽略的是:所有这些命令对**硬链接无效**——硬链接和原文件共享 inode,没有“指向”概念,
readlink对硬链接直接报invalid argument











