文件与目录管理¶
📌 学习时间:3-4天 📌 难度级别:⭐⭐ 基础 📌 前置知识:Linux基础入门
📚 章节概述¶
文件与目录管理是 Linux 最核心的操作技能。本章将全面介绍文件操作命令、权限管理体系(包括特殊权限 SUID/SGID/Sticky)、ACL 访问控制列表、硬链接与软链接、通配符模式匹配等,配合大量实操示例,帮助你真正掌握 Linux 文件管理。
🎯 学习目标¶
- 熟练使用文件与目录操作命令(ls/cd/mkdir/rm/cp/mv)
- 掌握文件查找工具(find/locate/which/whereis)
- 深入理解文件权限体系(rwx/chmod/chown/chgrp)
- 掌握特殊权限(SUID/SGID/Sticky Bit)
- 了解 ACL 扩展权限
- 理解硬链接与软链接的区别和应用场景
- 熟练使用通配符进行文件匹配
📖 1. 路径与目录导航¶
1.1 绝对路径与相对路径¶
# 绝对路径:从根目录 / 开始的完整路径
/home/alice/Documents/report.txt
/etc/nginx/nginx.conf
# 相对路径:相对于当前目录的路径
./report.txt # 当前目录下的文件(./ 可省略)
../config/app.conf # 上级目录的 config 下
../../shared/data # 上两级目录的 shared 下
# 特殊路径符号
. 当前目录
.. 上一级目录
~ 当前用户家目录
~bob 用户 bob 的家目录
- 上一次所在目录
1.2 目录导航命令¶
# cd - 切换目录(Change Directory)
cd /etc # 切换到 /etc 目录
cd ~ # 回到家目录
cd # 回到家目录(省略参数)
cd .. # 返回上级目录
cd - # 切换到上一次的目录
cd ~/Documents # 切换到家目录下的 Documents
# pwd - 显示当前工作目录(Print Working Directory)
pwd # /home/alice/Documents
pwd -P # 显示真实路径(解析符号链接)
# pushd / popd - 目录栈(重要的高效技巧)
pushd /var/log # 切换到 /var/log,并将当前目录压入栈
pushd /etc/nginx # 切换到 /etc/nginx,压入栈
dirs # 查看目录栈
popd # 弹出栈顶,返回 /var/log
popd # 弹出栈顶,返回原始目录
📖 2. 文件与目录基本操作¶
2.1 查看文件列表 - ls¶
# ls - 列出目录内容(List)
ls # 列出当前目录
ls /etc # 列出 /etc 目录
ls -l # 长格式显示(权限、大小、时间等)
ls -a # 显示隐藏文件(以.开头的文件)
ls -la # 长格式 + 隐藏文件
ls -lh # 人类可读的文件大小(1K, 2M, 3G)
ls -lt # 按修改时间排序(最新在前)
ls -ltr # 按修改时间倒序(最旧在前)
ls -lS # 按文件大小排序(最大在前)
ls -R # 递归列出子目录
ls -d */ # 只列出目录
ls -i # 显示 inode 号
ls -1 # 每行一个文件
# ls -l 输出详解
# -rw-r--r-- 1 alice developers 4096 Jan 15 10:30 report.txt
# │ │ │ │ │ │ │
# 类型+权限 链接数 所有者 所属组 大小 修改时间 文件名
2.2 创建文件与目录¶
# touch - 创建空文件 / 更新时间戳
touch file.txt # 创建空文件(如存在则更新时间戳)
touch file1.txt file2.txt # 创建多个文件
touch -t 202301150800 f.txt # 设置指定时间戳
# mkdir - 创建目录(Make Directory)
mkdir mydir # 创建目录
mkdir -p a/b/c/d # 递归创建多级目录(最常用)
mkdir -m 755 mydir # 创建并设置权限
mkdir dir1 dir2 dir3 # 同时创建多个目录
mkdir -p project/{src,bin,lib,doc,test} # 创建项目结构(花括号展开)
# 使用 cat / echo 创建带内容的文件
echo "Hello World" > hello.txt # 创建并写入
cat > config.txt << EOF # Here Document 创建文件
server=192.168.1.1
port=8080
EOF
2.3 复制文件与目录¶
# cp - 复制(Copy)
cp file1.txt file2.txt # 复制文件
cp file.txt /tmp/ # 复制到目标目录
cp -r dir1/ dir2/ # 递归复制目录(-r 必须用于目录)
cp -i file.txt /tmp/ # 覆盖前提示(interactive)
cp -v file.txt /tmp/ # 显示复制过程(verbose)
cp -p file.txt /tmp/ # 保留原文件属性(权限、时间戳)
cp -a dir1/ dir2/ # 归档复制(保留所有属性 = -rpd)
cp -u *.txt /backup/ # 只复制更新的文件(update)
# 复制多个文件
cp file1 file2 file3 /dest/ # 复制多个文件到目录
cp *.log /backup/logs/ # 使用通配符复制
2.4 移动与重命名¶
# mv - 移动/重命名(Move)
mv old.txt new.txt # 重命名文件
mv file.txt /tmp/ # 移动文件
mv dir1/ /opt/ # 移动目录(不需要 -r)
mv -i file.txt /tmp/ # 覆盖前提示
mv -v *.log /archive/ # 显示移动过程
mv -n file.txt /tmp/ # 不覆盖已存在文件(no-clobber)
mv -b file.txt /tmp/ # 覆盖前备份(创建 file.txt~ 备份文件)
# 批量重命名(使用 rename)
# Ubuntu: apt install rename
rename 's/\.txt$/\.md/' *.txt # .txt 改为 .md
rename 's/^/prefix_/' *.jpg # 添加前缀
rename 'y/A-Z/a-z/' *.TXT # 大写改小写
2.5 删除文件与目录¶
# rm - 删除(Remove)— 注意:Linux 没有回收站!
rm file.txt # 删除文件
rm -i file.txt # 删除前确认
rm -f file.txt # 强制删除(不提示)
rm -r dir/ # 递归删除目录
rm -rf dir/ # 强制递归删除(危险!)
rm -v *.log # 显示删除过程
# ⚠️ 危险命令警示
# rm -rf / # 删除整个系统(NEVER DO THIS!)
# rm -rf /* # 同上
# rm -rf $DIR/ # 如果 $DIR 为空,等同于 rm -rf /
# 安全的删除习惯
# 1. 先 ls 确认,再 rm
ls *.log # 先看看有哪些文件
rm *.log # 确认后再删除
# 2. 使用 trash-cli 替代 rm
# apt install trash-cli
trash-put file.txt # 放入回收站
trash-list # 查看回收站
trash-restore # 恢复文件
# rmdir - 删除空目录
rmdir empty_dir/ # 只能删除空目录
rmdir -p a/b/c/ # 递归删除空的父目录
📖 3. 文件查看命令¶
# cat - 查看文件内容(适合小文件)
cat file.txt # 查看文件
cat -n file.txt # 显示行号
cat -b file.txt # 只给非空行编号
cat file1 file2 > merged # 合并文件
# less - 分页查看(适合大文件,最常用)
less file.txt
# 操作:空格=下一页, b=上一页, /text=搜索, q=退出, G=末尾, g=开头
# more - 分页查看(只能向前翻页)
more file.txt
# head - 查看文件开头
head file.txt # 默认前10行
head -n 20 file.txt # 前20行
head -c 100 file.txt # 前100字节
# tail - 查看文件末尾
tail file.txt # 默认后10行
tail -n 20 file.txt # 后20行
tail -f /var/log/syslog # 实时跟踪文件更新(运维神器)
tail -F /var/log/syslog # 同上,文件被重建也能跟踪
# wc - 统计字数
wc file.txt # 行数 单词数 字节数
wc -l file.txt # 只统计行数
wc -w file.txt # 只统计单词数
wc -c file.txt # 只统计字节数
# nl - 带行号显示
nl file.txt
nl -b a file.txt # 所有行编号(包括空行)
# tac - 反向显示(cat 倒过来)
tac file.txt # 最后一行先显示
# rev - 每行字符翻转
echo "hello" | rev # olleh
📖 4. 文件查找¶
4.1 find - 实时搜索(最强大)¶
# 基本语法:find [搜索路径] [选项] [动作]
# 按名称查找
find / -name "*.log" # 在全盘查找 .log 文件
find /home -name "*.txt" # 在 /home 下查找
find . -name "config*" # 当前目录下查找以config开头的
find . -iname "readme*" # 忽略大小写查找
# 按类型查找
find /etc -type f # 普通文件
find /etc -type d # 目录
find /dev -type l # 符号链接
find /dev -type b # 块设备
# 按大小查找
find / -size +100M # 大于 100MB
find / -size -1k # 小于 1KB
find / -size 10M # 等于 10MB
# 按时间查找
find /var/log -mtime -7 # 7天内修改的
find /tmp -mtime +30 # 30天前修改的
find . -mmin -60 # 60分钟内修改的
find . -newer reference.txt # 比某个文件更新的
# 按权限查找
find / -perm 777 # 权限为 777 的
find / -perm -u+s # 设置了 SUID 的
find / -perm /o+w # 其他人可写的
# 按所有者查找
find /home -user alice # 属于 alice 的
find / -group developers # 属于 developers 组的
find / -nouser # 没有所有者的文件
# 组合条件
find / -name "*.log" -size +10M # 与(默认AND)
find / -name "*.jpg" -o -name "*.png" # 或(OR)
find / ! -name "*.txt" # 非(NOT)
# 执行动作
find /tmp -name "*.tmp" -delete # 删除找到的文件
find . -name "*.sh" -exec chmod +x {} \; # 对每个文件执行命令
find . -name "*.log" -exec ls -lh {} \; # 查看详情
find . -type f -exec grep -l "error" {} \; # 查找包含 error 的文件
# xargs 配合(更高效)
find . -name "*.txt" | xargs grep "pattern" # 在找到的文件中搜索
find . -name "*.log" | xargs -I {} mv {} /backup/ # 移动找到的文件
find . -name "*.tmp" -print0 | xargs -0 rm # 处理包含空格的文件名
# 实用组合示例
# 查找大于 50MB 的日志文件并按大小排序
find /var/log -name "*.log" -size +50M -exec ls -lh {} \; | sort -k5 -h
# 查找 7天内修改的配置文件
find /etc -type f -name "*.conf" -mtime -7
# 查找并清理空目录
find /path -type d -empty -delete
4.2 locate - 数据库搜索(快速)¶
# locate 使用预先建立的数据库搜索,速度极快
# 安装
sudo apt install mlocate # Ubuntu
sudo yum install mlocate # CentOS
# 更新数据库(新文件需要先更新才能搜到)
sudo updatedb
# 搜索
locate nginx.conf # 搜索包含此字符串的路径
locate -i readme # 忽略大小写
locate -c "*.log" # 只显示匹配数量
locate -n 10 "*.conf" # 只显示前10个结果
# locate vs find
# locate:快(查数据库),但可能不是最新的
# find:慢(实时搜索),但结果一定是最新的
4.3 which / whereis / type¶
# which - 在 PATH 中查找可执行文件
which python3 # /usr/bin/python3
which -a python # 显示所有匹配的
# whereis - 查找命令的二进制、源码和手册
whereis ls # ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz
whereis -b nginx # 只查二进制文件
whereis -m nginx # 只查手册页
# type - 显示命令类型
type cd # cd is a shell builtin
type ls # ls is aliased to 'ls --color=auto'
type /usr/bin/ls # /usr/bin/ls is /usr/bin/ls
📖 5. 文件权限¶
5.1 权限基础¶
# Linux 权限模型
# 每个文件有三组权限:所有者(Owner)、所属组(Group)、其他人(Others)
# 每组有三种权限:读(Read)、写(Write)、执行(eXecute)
# ls -l 输出的权限字段:
# -rwxr-xr-- 1 alice developers file.txt
# ||| ||| |||
# ||| ||| ||+-- 其他人: 读(r)
# ||| ||| |+--- 其他人: 无写(-)
# ||| ||| +---- 其他人: 无执行(-)
# ||| ||+------- 组: 读(r)
# ||| |+-------- 组: 无写(-)
# ||| +--------- 组: 执行(x)
# ||+------------ 所有者: 读(r)
# |+------------- 所有者: 写(w)
# +-------------- 所有者: 执行(x)
# 权限数字表示
# r = 4, w = 2, x = 1
# rwx = 4+2+1 = 7
# r-x = 4+0+1 = 5
# r-- = 4+0+0 = 4
# 常见权限组合
# 755 = rwxr-xr-x 目录、可执行文件
# 644 = rw-r--r-- 普通文件
# 700 = rwx------ 私有目录
# 600 = rw------- 私密文件(如SSH密钥)
# 777 = rwxrwxrwx 全部权限(不推荐用于生产环境)
5.2 chmod - 修改权限¶
# chmod - 修改文件权限
# 数字方式(最常用)
chmod 755 script.sh # rwxr-xr-x
chmod 644 config.txt # rw-r--r--
chmod 600 id_rsa # rw-------
chmod 700 private_dir/ # rwx------
# 符号方式
chmod u+x script.sh # 给所有者添加执行权限
chmod g+w file.txt # 给组添加写权限
chmod o-r file.txt # 移除其他人的读权限
chmod a+r file.txt # 给所有人添加读权限(a=all)
chmod u=rwx,g=rx,o=r file.txt # 精确设置
# 递归修改
chmod -R 755 project_dir/ # 递归修改目录和文件
chmod -R u+rwX project_dir/ # X: 只给目录和已有执行权限的文件添加执行权限
# 引用其他文件的权限
chmod --reference=file1.txt file2.txt # 让 file2 的权限和 file1 相同
5.3 chown / chgrp - 修改所有者和组¶
# chown - 修改所有者(需要 root 权限)
chown alice file.txt # 修改所有者
chown alice:developers file.txt # 同时修改所有者和组
chown :developers file.txt # 只修改组
chown -R alice:alice /home/alice/ # 递归修改
# chgrp - 修改所属组
chgrp developers file.txt # 修改组
chgrp -R developers project/ # 递归修改
5.4 特殊权限¶
SUID(Set User ID)¶
# SUID: 执行文件时,以文件所有者的身份运行(不是执行者的身份)
# 常见例子:passwd 命令需要修改 /etc/shadow,但普通用户没有权限
# passwd 设置了 SUID,执行时以 root 身份运行
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 Jul 15 00:00 /usr/bin/passwd
# ^
# s 表示 SUID 被设置
# 设置 SUID
chmod u+s executable # 符号方式
chmod 4755 executable # 数字方式(4 = SUID)
# 查找系统中所有 SUID 文件(安全审计时常用)
find / -perm -u+s -type f 2>/dev/null
SGID(Set Group ID)¶
# SGID 用于文件:执行时以文件所属组的身份运行
# SGID 用于目录:在该目录下创建的文件自动继承目录的组
# 团队协作场景
mkdir /shared/project
chgrp developers /shared/project
chmod g+s /shared/project # 设置 SGID
chmod 2775 /shared/project # 数字方式(2 = SGID)
# 验证:alice 在 /shared/project 创建的文件
# 自动属于 developers 组,而不是 alice 的默认组
touch /shared/project/newfile.txt
ls -l /shared/project/newfile.txt
# -rw-r--r-- 1 alice developers ...
# 查找 SGID 文件
find / -perm -g+s -type f 2>/dev/null
Sticky Bit(粘滞位)¶
# Sticky Bit:用于目录,只有文件所有者和 root 可以删除其中的文件
# 典型例子:/tmp 目录
ls -ld /tmp
# drwxrwxrwt 10 root root 4096 Jan 15 10:00 /tmp
# ^
# t 表示 Sticky Bit 被设置
# 设置 Sticky Bit
chmod +t shared_dir/ # 符号方式
chmod 1777 shared_dir/ # 数字方式(1 = Sticky)
# 效果:所有用户可以在 /tmp 创建文件
# 但 alice 不能删除 bob 创建的文件
特殊权限数字总结¶
# 四位数字权限:
# 第一位: 特殊权限
# 4 = SUID
# 2 = SGID
# 1 = Sticky Bit
# 后三位: 标准权限(owner/group/others)
chmod 4755 file # SUID + rwxr-xr-x
chmod 2775 dir # SGID + rwxrwxr-x
chmod 1777 dir # Sticky + rwxrwxrwx
chmod 6755 file # SUID + SGID + rwxr-xr-x
5.5 ACL(Access Control List)¶
# ACL 提供更精细的权限控制,可以为特定用户/组设置权限
# 查看 ACL
getfacl file.txt
# # file: file.txt
# # owner: alice
# # group: developers
# user::rwx
# group::r-x
# other::r--
# 设置 ACL
setfacl -m u:bob:rwx file.txt # 给 bob 用户 rwx 权限
setfacl -m g:testers:rx file.txt # 给 testers 组 rx 权限
setfacl -m u:charlie:--- file.txt # 禁止 charlie 任何访问
# 递归设置
setfacl -R -m u:bob:rx project_dir/ # 递归给 bob 读和执行权限
# 默认 ACL(对新创建的文件自动生效)
setfacl -d -m u:bob:rwx shared_dir/ # 目录下新文件自动给 bob rwx
# 删除 ACL
setfacl -x u:bob file.txt # 删除 bob 的 ACL
setfacl -b file.txt # 删除所有 ACL
# 备份和恢复 ACL
getfacl -R /project > acl_backup.txt # 备份
setfacl --restore=acl_backup.txt # 恢复
📖 6. 硬链接与软链接¶
6.1 概念对比¶
文件系统结构:
inode 100
┌─────────┐
文件名 ──────────►│ 元数据 │
│ 权限/大小 │
│ 时间戳 │──────► 数据块
│ 链接计数 │
└─────────┘
硬链接:多个文件名指向同一个 inode
┌──────────┐
│ file1.txt │─────┐
└──────────┘ │ inode 100
├──►┌─────────┐
┌──────────┐ │ │ 链接数=2 │──► 数据
│ file2.txt │─────┘ └─────────┘
└──────────┘
软链接:一个文件指向另一个文件名
┌──────────┐ inode 200 inode 100
│ link.txt │────►┌─────────┐ ┌─────────┐
└──────────┘ │"file.txt"│──►│ 实际数据 │
└─────────┘ └─────────┘
6.2 硬链接(Hard Link)¶
# 创建硬链接
ln original.txt hardlink.txt
# 验证:两个文件有相同的 inode
ls -li original.txt hardlink.txt
# 100 -rw-r--r-- 2 alice alice 100 Jan 15 file.txt
# 100 -rw-r--r-- 2 alice alice 100 Jan 15 hardlink.txt
# ^inode相同 ^链接数为2
# 硬链接的特点
# ✅ 修改任何一方,另一方同步更新(指向相同数据)
# ✅ 删除原文件,硬链接依然可用(数据未删除)
# ✅ 不能跨文件系统(必须在同一分区)
# ❌ 不能对目录创建硬链接(防止循环引用)
# ❌ 不能跨分区
echo "Hello World" > original.txt
ln original.txt link.txt
echo "Modified" >> original.txt
cat link.txt # 能看到 "Modified"
rm original.txt
cat link.txt # 仍然可用!
6.3 软链接 / 符号链接(Symbolic Link)¶
# 创建软链接(类似 Windows 的快捷方式)
ln -s /path/to/original.txt symlink.txt
ln -s /usr/local/bin/python3.10 /usr/local/bin/python3
# 验证
ls -l symlink.txt
# lrwxrwxrwx 1 alice alice 18 Jan 15 symlink.txt -> /path/to/original.txt
# ^
# l 表示这是一个符号链接
# 软链接的特点
# ✅ 可以跨文件系统/分区
# ✅ 可以对目录创建软链接
# ✅ 可以看到指向的目标(ls -l)
# ❌ 删除原文件后,软链接失效(悬空链接)
# ❌ 软链接有自己的 inode(不同于原文件)
# 常见应用
# 1. 版本切换
ln -sf /usr/local/java/jdk-17 /usr/local/java/current
# 2. 简化路径
ln -s /very/long/path/to/config /etc/myapp.conf
# 3. 共享库
ls -l /lib/x86_64-linux-gnu/libc.so*
# libc.so.6 -> libc-2.31.so
6.4 硬链接 vs 软链接总结¶
| 特性 | 硬链接 | 软链接 |
|---|---|---|
| inode | 与原文件相同 | 有自己的 inode |
| 跨文件系统 | ❌ 不可以 | ✅ 可以 |
| 链接目录 | ❌ 不可以 | ✅ 可以 |
| 原文件删除 | 不影响,数据依然在 | 失效(悬空链接) |
| 文件大小 | 与原文件相同 | 存储目标路径的大小 |
| 相对路径 | N/A | 相对于链接所在目录 |
| 识别方式 | ls -i 看 inode | ls -l 看 -> 指向 |
📖 7. 通配符(Globbing)¶
# Shell 通配符用于文件名匹配模式
# * 匹配任意数量的任意字符
ls *.txt # 所有 .txt 文件
ls file* # 以 file 开头的所有文件
ls *report* # 包含 report 的所有文件
# ? 匹配单个任意字符
ls file?.txt # file1.txt, fileA.txt 等
ls ???.log # 三个字符的 .log 文件
# [] 匹配方括号内的任一字符
ls file[123].txt # file1.txt, file2.txt, file3.txt
ls file[a-z].txt # filea.txt, fileb.txt, ...
ls file[!0-9].txt # 非数字的(file 后面一个非数字字符)
ls [A-Z]*.txt # 大写字母开头的 .txt 文件
# {} 花括号展开(Brace Expansion,不是通配符但很实用)
echo {a,b,c} # a b c
mkdir dir_{01..10} # 创建 dir_01 到 dir_10
cp file.{txt,bak} # 等同于 cp file.txt file.bak
touch {jan,feb,mar}_{2024,2025}.log # 创建6个文件
# 实用示例
# 复制所有非 .log 文件
cp !(*.log) /backup/ # 需要 shopt -s extglob
# 扩展通配符(需开启 extglob)
shopt -s extglob
ls !(*.log) # 排除 .log 文件
ls @(*.txt|*.md) # .txt 或 .md 文件
ls ?(ab)c # c 或 abc
ls +(ab) # ab, abab, ababab...
ls *(ab) # 空, ab, abab, ababab...
📖 8. 文件属性¶
# stat - 查看文件详细信息
stat file.txt
# File: file.txt
# Size: 4096 Blocks: 8 IO Block: 4096 regular file
# Device: fd01h/64769d Inode: 131073 Links: 1
# Access: (0644/-rw-r--r--) Uid: ( 1000/ alice) Gid: ( 1000/ alice)
# Access: 2024-01-15 10:30:00.000000000 +0800
# Modify: 2024-01-15 10:30:00.000000000 +0800
# Change: 2024-01-15 10:30:00.000000000 +0800
# 三种时间
# atime (Access time): 最后访问时间
# mtime (Modify time): 最后内容修改时间
# ctime (Change time): 最后元数据修改时间(权限、所有者等)
# lsattr / chattr - 文件特殊属性
lsattr file.txt # 查看特殊属性
# 设置不可修改属性(即使 root 也不能删除/修改)
sudo chattr +i important.conf # 设置 immutable
sudo chattr -i important.conf # 取消 immutable
# 设置只能追加属性(适合日志文件)
sudo chattr +a logfile.log # 只能追加,不能删除/修改已有内容
📖 9. 实战示例¶
示例1:项目目录结构创建¶
#!/bin/bash
# 创建标准 Web 项目目录结构
PROJECT="mywebapp"
mkdir -p "$PROJECT"/{src/{main/{java,resources},test},docs,scripts,config}
mkdir -p "$PROJECT"/src/main/java/com/example/{controller,service,model,config}
mkdir -p "$PROJECT"/src/main/resources/{static/{css,js,images},templates}
# 创建基本文件
touch "$PROJECT"/README.md
touch "$PROJECT"/.gitignore
touch "$PROJECT"/config/{dev,test,prod}.properties
# 设置权限
chmod -R 755 "$PROJECT"/scripts/
chmod 644 "$PROJECT"/config/*.properties
# 显示结构
tree "$PROJECT"
示例2:批量文件整理¶
#!/bin/bash
# 按文件扩展名分类整理文件
SRC_DIR="$HOME/Downloads"
DEST_DIR="$HOME/Organized"
# 创建分类目录
mkdir -p "$DEST_DIR"/{Images,Documents,Videos,Music,Archives,Others}
# 分类移动
cd "$SRC_DIR"
for file in *; do
[ -f "$file" ] || continue # &&前一个成功才执行后一个;||前一个失败才执行
case "${file##*.}" in
jpg|jpeg|png|gif|bmp|svg) mv "$file" "$DEST_DIR/Images/" ;;
pdf|doc|docx|txt|md|xlsx) mv "$file" "$DEST_DIR/Documents/" ;;
mp4|avi|mkv|mov|wmv) mv "$file" "$DEST_DIR/Videos/" ;;
mp3|wav|flac|aac) mv "$file" "$DEST_DIR/Music/" ;;
zip|tar|gz|bz2|xz|rar) mv "$file" "$DEST_DIR/Archives/" ;;
*) mv "$file" "$DEST_DIR/Others/" ;;
esac
done
echo "文件整理完成!"
示例3:权限审计脚本¶
#!/bin/bash
# 检查系统中可能不安全的文件权限
echo "=== 安全权限审计报告 ==="
echo "生成时间: $(date)"
echo ""
# 1. 查找全局可写文件
echo "--- 全局可写文件(非 /tmp 和 /proc)---"
find / -path /tmp -prune -o -path /proc -prune -o \
-type f -perm -o+w -print 2>/dev/null
# 2. 查找无主文件
echo ""
echo "--- 无主文件 ---"
find / -path /proc -prune -o -nouser -print 2>/dev/null
# 3. 查找 SUID/SGID 文件
echo ""
echo "--- SUID 文件 ---"
find / -perm -u+s -type f 2>/dev/null
echo ""
echo "--- SGID 文件 ---"
find / -perm -g+s -type f 2>/dev/null
# 4. 检查关键文件权限
echo ""
echo "--- 关键文件权限检查 ---"
for file in /etc/passwd /etc/shadow /etc/sudoers; do # Shell for循环
if [ -f "$file" ]; then # 条件测试:-f文件存在 -d目录存在 -z空字符串
echo "$file: $(stat -c '%a %U:%G' "$file")" # $()命令替换:执行命令并获取输出
fi
done
📖 10. 面试要点¶
高频面试题¶
Q1:硬链接和软链接的区别?什么场景使用哪种?
硬链接与原文件共享 inode,删除原文件不受影响,但不能跨文件系统、不能链接目录。软链接有独立 inode、存储指向路径,可以跨文件系统、可以链接目录,但原文件删除会导致悬空链接。版本切换用软链接(如 java/current -> jdk-17),数据备份/防误删用硬链接。
Q2:解释 chmod 755 的含义
755 = rwxr-xr-x。所有者有读、写、执行权限(7=4+2+1),组用户和其他用户有读和执行权限(5=4+0+1)。常用于目录和可执行脚本。
Q3:什么是 SUID?有什么安全风险?
SUID(Set User ID) 使程序在执行时以文件所有者身份运行。如
passwd命令以 root 身份运行来修改/etc/shadow。安全风险:如果 SUID 程序有漏洞,攻击者可能获得 root 权限。应定期审计 SUID 文件:find / -perm -u+s -type f
Q4:find 和 locate 的区别?
find实时遍历文件系统,结果准确但较慢;locate查询预建数据库,极快但可能不是最新的,需要updatedb更新数据库。生产环境排障用find,日常快速查找用locate。
Q5:如何找出系统中大于 100MB 的文件?
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -h # |管道:将前一命令的输出作为后一命令的输入
# 或
du -ah / 2>/dev/null | sort -rh | head -20
🔧 练习题¶
基础练习¶
- 创建目录结构
~/practice/{dir1,dir2,dir3}/{sub1,sub2}并验证 - 创建一个文件,分别给所有者 rwx、组 rx、其他 r 权限
- 创建一个硬链接和一个软链接,删除原文件后分别查看效果
进阶练习¶
- 使用
find查找/var/log下 7 天内修改过的大于 1MB 的文件 - 为共享目录设置 SGID,验证新文件的组继承
- 使用 ACL 让特定用户对文件有只读权限
综合练习¶
- 编写脚本:自动创建项目目录结构并设置合适的权限
- 编写脚本:查找并报告系统中的 SUID 文件
- 编写脚本:按文件类型自动整理 Downloads 目录
✅ 自我检查¶
- 能熟练使用 ls/cd/cp/mv/rm/mkdir 等命令
- 能用 find 进行各种条件的文件搜索
- 理解 rwx 权限模型和数字表示
- 知道 SUID/SGID/Sticky Bit 的作用和使用场景
- 能区分硬链接和软链接
- 能使用 ACL 设置精细权限
- 能编写文件管理相关的 Shell 脚本
上一章:01-Linux基础入门 下一章:03-文本处理三剑客