ln(link的缩写)命令主要用于在文件之间创建链接:
| 特性 | 硬链接 | 软链接 |
|---|---|---|
| 创建命令 | ln 源文件 目标文件 |
ln -s 源文件 目标文件 |
| inode号码 | 与源文件相同 | 与源文件不同 |
| 跨文件系统 | 不支持 | 支持 |
| 目录链接 | 不支持(超级用户除外) | 支持 |
| 源文件删除 | 链接仍然有效 | 链接失效(悬空链接) |
| 文件大小 | 与源文件相同 | 路径名的长度 |
| ls -l 显示 | 正常文件显示 | lrwxrwxrwx 并显示指向 |
# 创建硬链接
ln [选项] 源文件 [目标文件]
# 创建软链接
ln [选项] 源文件 [目标文件]
| 选项 | 说明 |
|---|---|
| -s, --symbolic | 创建符号链接(软链接) |
| -f, --force | 强制创建,覆盖已存在的目标文件 |
| -i, --interactive | 覆盖前提示确认 |
| -n, --no-dereference | 将符号链接的目标视为普通文件 |
| -b, --backup | 为每个已存在的目标文件创建备份 |
| -d, -F, --directory | 允许超级用户创建目录的硬链接 |
| -L, --logical | 解引用符号链接中的符号链接 |
| -P, --physical | 直接使用符号链接本身 |
| -r, --relative | 创建相对于链接位置的符号链接 |
| -t, --target-directory=目录 | 在指定目录中创建链接 |
| -T, --no-target-directory | 始终将目标文件视为普通文件 |
| -v, --verbose | 显示详细操作信息 |
| --help | 显示帮助信息 |
| --version | 显示版本信息 |
Linux文件系统中,每个文件都有一个唯一的inode(索引节点),包含文件的元数据(权限、所有者、时间戳等)和指向数据块的指针。
硬链接是同一个inode的多个目录条目。删除一个硬链接不会影响其他链接,只有当所有硬链接都被删除时,文件数据才会被释放。
软链接是一个特殊的文件,包含指向目标文件路径的文本。它有自己的inode,通过路径名引用目标文件。
为文件创建硬链接:
# 创建硬链接
ln original.txt hardlink.txt
# 验证链接(inode相同)
ls -li original.txt hardlink.txt
259105 -rw-r--r-- 2 user group 1024 Jan 1 10:00 hardlink.txt
259105 -rw-r--r-- 2 user group 1024 Jan 1 10:00 original.txt
注意:第二列的数字"2"表示该inode有两个硬链接。
为文件创建符号链接:
# 创建软链接
ln -s original.txt symlink.txt
# 验证链接
ls -l symlink.txt
lrwxrwxrwx 1 user group 12 Jan 1 10:00 symlink.txt -> original.txt
为目录创建符号链接:
# 创建目录软链接
ln -s /var/log logs
# 使用链接
ls logs/
cd logs/
使用 -f 选项强制覆盖:
ln -sf new_target.txt existing_symlink
使用 -i 选项在覆盖前确认:
ln -si original.txt existing_file
ln: replace 'existing_file'? y
使用 -r 选项创建相对路径链接:
# 绝对路径链接
ln -s /home/user/documents/file.txt abs_link
# 相对路径链接
ln -sr /home/user/documents/file.txt rel_link
使用 -t 选项在指定目录创建链接:
ln -st /home/user/links/ file1.txt file2.txt file3.txt
使用 -v 选项显示操作详情:
ln -sv original.txt new_link
'new_link' -> 'original.txt'
创建指向当前版本的软链接:
# 部署新版本
cp -r app-v2.1.0/ /srv/www/
ln -sf /srv/www/app-v2.1.0 /srv/www/current
链接用户配置文件:
# 备份原配置
mv ~/.bashrc ~/.bashrc.backup
# 链接到版本控制的配置
ln -s ~/dotfiles/bashrc ~/.bashrc
创建库版本链接:
# 创建库链接
ln -s libexample.so.1.2.3 libexample.so.1
ln -s libexample.so.1 libexample.so
使用链接管理日志文件:
# 重命名当前日志
mv app.log app.log.20230101
# 创建新日志文件
touch app.log
# 或者重新创建软链接
ln -sf /var/log/app/app.log /var/log/app.log
使用循环批量创建链接:
# 为目录中所有.txt文件创建链接
for file in *.txt; do
ln -s "$(pwd)/$file" "/home/user/links/$file"
done
查找并处理失效的软链接:
# 查找悬空链接
find /path -type l -! -exec test -e {} \; -print
# 修复悬空链接脚本
for link in $(find /path -type l -! -exec test -e {} \; -print); do
target=$(readlink "$link")
if [ -f "/new/path/$target" ]; then
ln -sf "/new/path/$target" "$link"
echo "修复链接: $link"
fi
done
使用备份功能:
# 创建备份(如果目标存在)
ln -sb new_file existing_link
创建跨目录的相对链接:
# 从 /home/user/project/bin 链接到 /home/user/project/src/file
ln -sr ../src/file.txt script_link
# 查看软链接指向
readlink symlink_name
# 查看文件的所有硬链接
find / -inum $(ls -i filename | awk '{print $1}') 2>/dev/null
# 查看文件的硬链接数
ls -l filename
# 第二列的数字就是硬链接数
# 检查是否为软链接
if [ -L "filename" ]; then
echo "这是一个软链接"
fi
# 检查是否为硬链接
if [ "$(stat -c %h "filename")" -gt 1 ]; then
echo "这个文件有多个硬链接"
fi
| 问题 | 解决方案 |
|---|---|
| "链接层数过多"错误 | 检查是否存在循环链接,使用 namei 命令追踪链接 |
| 硬链接创建失败 | 检查是否跨文件系统,使用 df -T 文件名 查看文件系统 |
| 权限被拒绝 | 检查目录写权限,或使用sudo |
| 链接指向错误 | 使用 readlink 检查链接目标,重新创建 |
| 悬空链接 | 找到源文件重新创建,或删除失效链接 |