BOSh
文章355
标签611
分类151

文章分类

315晚会 36氪 80后 ADB AI AI Agent AI PC AI 代理 AI 助手 AI 网关 AI 评测 AIStudio AI代理 AI助手 AI处理器 AI大模型 AI安全 AI应用 AI智能体 AI网关 AMD API API 集成 AWS Active Directory Agent Agentic AI AionUi Alwaysdata Android Apple Arch Linux Argo Tunnel Automation Backup Bash Bosh Bot Bot-hosting C++ CDN CEO CI/CD CLI CLI Proxy API CLIProxyAPI COMPUTEX CRM CT8 CentOS 7 Chrome 插件 Cisco Claude Claude Opus 4.6 Cloudflare Code ConnectBot Credential Manager Ct8.pl CurrentEvents DHCP DNS Debian DeepSeek DenchClaw Deployment DevOps Devil Docker Elon Musk Express FSRM FTP FreeBSD FreeLLMAPI GCP GEO GPL GPO GPS GPT GPU Gemini Gemini 3.1 Pro Ghostty Git GitHub GitHub Actions Gmail Go Gog Golang Google Google AI Pro Google API Google Cloud Google Gemini Google Photos Google Pixel HDC HKUDS Hardware HarmonyOS Hermes Hermes Agent Hexo HidenCloud Hugo Hyper-V Hyprland IIS IPV6 Intel JavaScript Jetpack Compose John Turnus KDE KOSPI Karpathy Kimi-K2.5 Kotlin LINUX LLM LTS LVM LaTeX Linux LiveUSB MBR MTProto MW4L Markdow Markdown Matrix MemU Bot Mesh-Network MiniMax Musk MyDevil NAT NAT64 NIX NODE NTFS NVIDIA NVIDIA Build NanoClaw Netcatty Netlify Newsletter Node.js Nvidia Open WebUI OpenAI OpenAI 兼容接口 OpenAI兼容 OpenCLI OpenClaw P2P PDF 编译 PV Packet Tracer Pacman Phusion Passenger PicoClaw Pixel Pixel 1 Pixel 12 Pixel11 Plasma PowerShell Prismer Productivity Pura90 Python QClaw QQ机器人 Qualcomm Quickshell R22 RAG RAID RAID5 RIP RIPv2 RTX Spark Railway Reddit Rust SFTP SMB SSH SeleniumBase Serv00 Serverless Shell Sing-box Skills SoC Sub-Store Subagent SuperCall Synapse Syncthing TPU TSMC Tailscale Telegram Telegram Bot Tensor Tensor G7 Tim Cook Tunnel Turnstile Ubuntu VG VLESS VMware VPN VPS Vercel Vite Wayland WeChat Web3 WebSSH WebSocket WebTransport Web开发 Windows Windows 11 Windows Admin Center Windows Server Windows Server 2022 WireGuard WorkBuddy X XChat XHTTP X热榜 YUM源 YouTube ZeroClaw arXiv arch c++ cc-switch cloudflared ct8.pl email find git hdc hidumper hugo hyprmod i3wm iMessage iOS iSCSI icacls mdadm n8n nanobot node js ntfs pacman pnpm podman sconfig zz.ac 东海 两性关系 个人助理 中东 中东冲突 中东局势 中关村论坛 中南大学 中国 中美 中美关系 乌克兰 习惯养成 云同步 云服务器 亚洲 人性 人教版 代理 代金券 以色列 任务管理 伊朗 伊朗危机 伊朗战争 伦理 体育 使用 俄乌战争 俄罗斯 保护主义 信息流 信息管理 停火 健康管理 光通信 免费VPS 免费主机 免费试用 全球动态 六年级 共和党 关系 养老金 内存分析 内存管理 内容工厂 内容生产 内容筛选 内网穿透 军事冲突 军事动态 军民融合 农村 分享 分配 刘欢 创业 制裁 办公自动化 加密 加密货币 加沙 北斗 北韩 医学生 半导体 华为 协议分析 博客 博客助手 博客发布 博客部署成功 卫星 即时通讯 厄尔尼诺 原生 JS 去中心化 反向代理 反思 反爬虫 反重力 台海局势 台湾 命令 命令行 喷嚏网 国产 国产化 国产替代 国宴 国际 国际关系 国际局势 国际新闻 图卦 图说 地缘政治 域名解析 域名邮箱 域控 基础设施 多代理 多模态AI 大学分析 大模型 存储 存储空间 存储管理 孙少平 学习 安全 安装 实时监控 家庭助理 家庭服务器 家装设计 小学 嵌套虚拟化 工业策略 工作总结 工作效率 工作流编排 工具 工具链 平凡的世界 平台责任 庞氏骗局 开发 开发实录 开发指南 开发调试 开源 开源软件 开源项目 张雪峰 微信 心理健康 快捷键 怀念 性能调优 情感 慈善 战争 房地产 手机 技术分享 投资工具 指标看板 提示词工程 播客 收件箱清理 故障转移群集 效率 效率工具 教程 教育制度 数学 数据分析 数据投毒 文件服务器 文件管理 文献管理 新能源汽车 新闻汇总 日历聚合 时事 时事总结 显卡 晨报 智能体 智能体生态 智能手机 服务器管理 服务器部署 朝鲜 权限 极端天气 架构 架构实践 核协议 核武器 桌面Cowork 桌面环境 模型接入 模型配置 欧洲安全 每日图说 比亚迪 气候 油价 法律 活动运营 浏览器自动化 消息通道 消费者权益 深度学习 渔船 游戏开发 湘雅医院 潘石屹 热点新闻 熔断 版本更新 特朗普 生态系统 生活 生活自动化 生物识别 用例 甲骨文云 电池技术 症状追踪 白嫖 白嫖攻略 白山云 皮皮虾 监管 目标管理 省钱 知识库 磁盘管理 社交媒体 社会保障 社会公平 社会百态 社会观察 科技 科普 科研助手 窗口管理 笔记 第一财经 算法 算法推荐 系统管理 纽森 组策略 组网 经济 经济观察 经验分享 编程 网关 网络 网络安全 网络实验 网络摘录 网络穿透 网络规划 网络配置 美伊冲突 美伊谈判 美国 美国制裁 美国大选 美国政治 股灾 能源安全 脚本 腾讯 腾讯,龙虾,OpenClaw 腾讯云 自动化 自动化创作 自动化协作 自动化提醒 自动化流水线 自动化脚本 自动化运维 自建服务 自律教练 自托管 自由软件 节点管理 芯片 草榴 虚拟化 虚拟化运维 虚拟机 行为改变 视频摘要 解锁 计算摄影 订阅系统 记录 许可证 论文写作 论文阅读 语义搜索 语音代理 读书 读书笔记 读后感 谷歌云 财报季 账单分析 路由协议 路由器 路由配置 路遥 身份验证 轻量级 迁移 运维 进化论 远程桌面 远程访问 远程运维 选车 邀请确认 部署 部署指南 部署教程 重复数据删除 量子计算 销售自动化 阅读感悟 随笔 隐私 霍尔木兹 霍尔木兹海峡 青蛙机 韩国股市 韩红 韬定律 音乐 项目管理 风险管理 飞书 高中生活 高可用 高考 高考志愿 鸽巢原理 麒麟 麒麟9050 黄仁勋 黎巴嫩 龙虾

一言

文章归档

Linux find 命令从入门到实战:循序渐进训练计划

Linux find 命令从入门到实战:循序渐进训练计划

title: Linux find 命令从入门到实战:循序渐进训练计划
slug: 1790409995201
date: 2026-09-26
summary: 从按名称查找到定时日志归档脚本,一份循序渐进的 find 命令训练计划,附 3 个可直接使用的完整运维脚本。
tags:

  • Linux
  • find
  • Shell
  • 运维

find 是 Linux 下最强大的文件查找工具之一,但它的参数多、组合灵活,很多初学者望而却步。这篇文章给你一份循序渐进的训练计划:从基础查找到 3 个真实运维场景的完整脚本,跟着练一遍,find 就真正变成你的肌肉记忆了。

准备工作:搭建练习环境

动手之前,先创建一个测试目录,造一些文件用来练手:

1
2
3
4
5
mkdir -p ~/find_test && cd ~/find_test
touch file1.txt file2.log .hidden_file script.sh large_file.bin
mkdir -p sub1/sub2
touch sub1/a.txt sub1/sub2/b.log
chmod 777 script.sh

建议每学一个命令,都在这个目录里实际跑一遍,看输出是否符合预期。

第一阶段:按名称与类型查找

题目 1:按名称查找 .log 文件

查找当前目录下所有以 .log 结尾的文件:

1
find . -name "*.log"

如果想不区分大小写(比如同时匹配 .LOG),用 -iname:

1
find . -iname "*.log"

题目 2:只查找目录

1
find . -type d

-type 是最常用的过滤条件之一:f 表示普通文件,d 表示目录,l 表示符号链接。

题目 3:查找隐藏文件

Linux 下以 . 开头的是隐藏文件:

1
find . -name ".*"

第二阶段:按大小与时间查找

题目 4:查找大于 10MB 的文件

1
find . -size +10M

-size 的单位很有讲究:+10M 表示大于 10MB,-10M 表示小于 10MB,10M 表示约等于。单位还可以用 k(KB)、G(GB)、c(字节)。

题目 5:查找 24 小时内修改过的文件

1
2
3
find . -mtime -1
# 或者用分钟粒度:
find . -mmin -1440

-mtime -1 表示修改时间在 1 天以内,-mmin -1440 是同样的意思(24×60=1440 分钟)。

题目 6:查找 7 天前被访问过的文件

1
find . -atime +7

注意这里是 +7(7 天以前),不是 -7。atime 是访问时间,mtime 是修改时间,ctime 是状态改变时间——三者的区别是面试常客,值得记住。

第三阶段:深度、权限与逻辑组合

题目 7:限制查找深度

只在当前目录下找 .txt 文件,最多深入两层子目录:

1
find . -maxdepth 2 -name "*.txt"

-maxdepth 建议放在其他条件前面,否则在某些 find 实现里会给出警告。

题目 8:在 /var/log 下不区分大小写找日志

1
find /var/log -iname "*.log"

题目 9:按权限查找

查找权限为 777 的文件(安全排查常用):

1
sudo find /var -perm 777 -ls

-perm 777 是精确匹配;-perm -777 表示"至少包含"这些权限位;-perm /777 表示"包含其中任意"。排查可疑文件时 -perm -4000(找 SUID 文件)也很常用。

题目 10:逻辑或组合

查找 .jpg 或 .png 图片:

1
find /data \( -name "*.jpg" -o -name "*.png" \)

括号需要转义(或加引号),否则 shell 会误解。-o 是 OR,-a 是 AND(默认可省略),! 是 NOT。

题目 11:排除 .git 目录

查找所有 .sh 脚本,但跳过 .git:

1
find . -path "*/.git" -prune -o -name "*.sh" -print

这行值得拆开理解,它本质是个 if-else:

  • -path "*/.git":当前路径是不是 .git 目录?
  • -prune:如果是,直接剪掉这根"树枝",不往下递归
  • -o:否则,执行后面的逻辑
  • -name "*.sh" -print:匹配 .sh 并打印

第四阶段:用 -exec 处理查找结果

题目 12:交互式删除 30 天前的临时文件

1
find /tmp -name "*.tmp" -mtime +30 -ok rm {} \;

-ok 和 -exec 一样执行命令,但每个文件都会先问你确认。批量删除前先用 -ok,或者先不加删除动作 dry-run 跑一遍,是保命的好习惯。

题目 13:批量修改目录权限为 755

1
find /var/www/html -type d -exec chmod 755 {} \;

{} 是查找到的文件的占位符,\; 表示命令结束。如果文件很多,用 + 代替 \; 可以把多个文件拼成一条命令执行,效率更高:

1
find /var/www/html -type d -exec chmod 755 {} +

题目 14:复制小配置文件到备份目录

1
2
mkdir -p /backup/config
find . -name "*.conf" -size -10k -exec cp {} /backup/config/ \;

注意提前建好目标目录,否则 cp 会报错。

综合实战:3 个完整脚本

前面都是单条命令,下面是 3 个真实运维/开发场景的完整脚本。需求来自实战,脚本逐行写好并加了注释,可以直接拿去用。

实战 1:定时日志清理与归档脚本

场景:服务器日志占满磁盘,需要定期归档旧日志并清理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/bin/bash
#
# archive_old_logs.sh - 日志归档清理脚本
# 功能:查找指定目录下超过 7 天未修改的 .log 文件,
# 打包为 old_logs_<日期>.tar.gz 存到 /tmp/backup/,验证无误后删除原文件
# 用法:./archive_old_logs.sh /var/log/app
# 建议:配合 crontab 每天凌晨执行
# 0 2 * * * /path/to/archive_old_logs.sh /var/log/app >> /var/log/archive.log 2>&1

set -euo pipefail

# ---------- 1. 参数校验 ----------
LOG_DIR="${1:-}"
if [ -z "$LOG_DIR" ]; then
echo "用法: $0 <日志目录>"
echo "示例: $0 /var/log/app"
exit 1
fi

if [ ! -d "$LOG_DIR" ]; then
echo "错误: 目录 '$LOG_DIR' 不存在"
exit 1
fi

BACKUP_DIR="/tmp/backup"
DATE_STR=$(date +%Y%m%d)
ARCHIVE_PATH="${BACKUP_DIR}/old_logs_${DATE_STR}.tar.gz"
mkdir -p "$BACKUP_DIR"

# ---------- 2. 查找旧日志 ----------
echo "正在扫描 $LOG_DIR ..."
mapfile -t OLD_FILES < <(find "$LOG_DIR" -type f -name "*.log" -mtime +7 -print)

if [ ${#OLD_FILES[@]} -eq 0 ]; then
echo "没有发现超过 7 天未修改的 .log 文件,无需处理"
exit 0
fi

echo "发现 ${#OLD_FILES[@]} 个旧日志文件:"
printf ' %s\n' "${OLD_FILES[@]}"

# ---------- 3. 打包归档 ----------
echo "正在打包到 $ARCHIVE_PATH ..."
# -print0 + --null 可正确处理带空格/特殊字符的文件名
find "$LOG_DIR" -type f -name "*.log" -mtime +7 -print0 \
| tar --null -czf "$ARCHIVE_PATH" --files-from=- --no-recursion

if [ ! -s "$ARCHIVE_PATH" ]; then
echo "错误: 打包失败,保留原文件"
exit 1
fi
echo "打包成功: $ARCHIVE_PATH ($(du -h "$ARCHIVE_PATH" | cut -f1))"

# ---------- 4. 校验归档完整性,通过后再删除 ----------
echo "正在校验归档文件..."
if tar -tzf "$ARCHIVE_PATH" > /dev/null 2>&1; then
echo "校验通过,删除原文件..."
find "$LOG_DIR" -type f -name "*.log" -mtime +7 -delete
echo "清理完成,共删除 ${#OLD_FILES[@]} 个文件"
else
echo "错误: 归档文件损坏,保留原文件以防数据丢失"
exit 1
fi

设计要点:

  • 先打包、校验通过后再删除,任何一步失败都不会丢数据
  • 用 -print0 + tar --null 处理文件名中的空格和特殊字符
  • set -euo pipefail 让脚本遇到错误立即退出,避免误删文件

实战 2:代码库大文件与敏感信息排查脚本

场景:提交代码前,检查是否误带了大文件或私钥。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/bin/bash
#
# precommit_check.sh - 提交前检查脚本
# 功能:扫描项目目录(忽略 .git),找出大于 10MB 的文件和敏感私钥文件
# 用法:在项目根目录执行 ./precommit_check.sh [目录]
# 建议:做成 git pre-commit hook,提交时自动检查

set -euo pipefail

SCAN_DIR="${1:-.}"
SIZE_LIMIT_MB=10
FOUND_ISSUE=0

echo "正在扫描: $SCAN_DIR"
echo "======================================"

# ---------- 1. 大文件检查 ----------
echo "[1/2] 检查大文件 (>${SIZE_LIMIT_MB}MB)..."
mapfile -t BIG_FILES < <(find "$SCAN_DIR" -path "*/.git" -prune -o -type f -size +${SIZE_LIMIT_MB}M -print)

if [ ${#BIG_FILES[@]} -eq 0 ]; then
echo " ✓ 未发现大文件"
else
FOUND_ISSUE=1
echo " ⚠ 发现 ${#BIG_FILES[@]} 个大文件:"
for f in "${BIG_FILES[@]}"; do
SIZE_MB=$(du -m "$f" | cut -f1)
echo " ${SIZE_MB}MB $f"
done
fi

echo ""

# ---------- 2. 敏感文件检查 ----------
echo "[2/2] 检查敏感文件 (.key / .pem / id_rsa)..."
mapfile -t SENSITIVE < <(find "$SCAN_DIR" -path "*/.git" -prune -o -type f \
\( -name "*.key" -o -name "*.pem" -o -name "*id_rsa*" \) -print)

if [ ${#SENSITIVE[@]} -eq 0 ]; then
echo " ✓ 未发现敏感文件"
else
FOUND_ISSUE=1
echo " ⚠ 警告!发现 ${#SENSITIVE[@]} 个疑似敏感文件:"
printf ' %s\n' "${SENSITIVE[@]}"
echo " 请确认这些文件不在 git 追踪范围内!"
fi

echo "======================================"
if [ $FOUND_ISSUE -eq 0 ]; then
echo "检查通过,可以安全提交"
exit 0
else
echo "发现问题,请处理后再提交"
exit 1
fi

设计要点:

  • 用 -path "*/.git" -prune 跳过 git 内部目录,避免误报
  • 非零退出码可以直接接入 git hook,拦截问题提交
  • 还可以扩展:检查 .env、*password*、*.p12 等

实战 3:Web 目录权限批量安全修复脚本

场景:Web 服务器安全加固,规范文件/目录权限与所有者。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/bin/bash
#
# fix_web_perm.sh - Web 目录权限修复脚本
# 功能:目录设为 755,文件设为 644,所有者修正为 Web 用户
# 用法:sudo ./fix_web_perm.sh /var/www/wordpress [web_user]

set -euo pipefail

TARGET_DIR="${1:-}"
WEB_USER="${2:-www-data}"

# ---------- 1. 参数与环境检查 ----------
if [ -z "$TARGET_DIR" ]; then
echo "用法: $0 <目标目录> [Web用户]"
echo "示例: $0 /var/www/wordpress www-data"
exit 1
fi

if [ ! -d "$TARGET_DIR" ]; then
echo "错误: 目录 '$TARGET_DIR' 不存在"
exit 1
fi

if [ "$(id -u)" -ne 0 ]; then
echo "警告: 修改文件所有者需要 root 权限,建议用 sudo 运行"
fi

echo "目标目录: $TARGET_DIR"
echo "Web 用户: $WEB_USER"
echo "======================================"

# ---------- 2. 目录权限 755 ----------
echo "[1/3] 设置目录权限为 755..."
DIR_COUNT=$(find "$TARGET_DIR" -type d | wc -l)
find "$TARGET_DIR" -type d -exec chmod 755 {} +
echo " 已处理 $DIR_COUNT 个目录"

# ---------- 3. 文件权限 644 ----------
echo "[2/3] 设置文件权限为 644..."
FILE_COUNT=$(find "$TARGET_DIR" -type f | wc -l)
find "$TARGET_DIR" -type f -exec chmod 644 {} +
echo " 已处理 $FILE_COUNT 个文件"

# ---------- 4. 修正所有者 ----------
echo "[3/3] 修正所有者为 ${WEB_USER}:${WEB_USER}..."
if id "$WEB_USER" &>/dev/null; then
WRONG_COUNT=$(find "$TARGET_DIR" ! -user "$WEB_USER" | wc -l)
if [ "$WRONG_COUNT" -gt 0 ]; then
find "$TARGET_DIR" ! -user "$WEB_USER" -exec chown "${WEB_USER}:${WEB_USER}" {} +
echo " 已修正 $WRONG_COUNT 个文件的所有者"
else
echo " 所有者均正确,无需修改"
fi
else
echo " 警告: 用户 '$WEB_USER' 不存在,跳过所有者修正"
fi

echo "======================================"
echo "权限修复完成"

设计要点:

  • 用 {} + 代替 {} \;,把多个文件合并为少量 chmod/chown 调用,大目录下快得多
  • ! -user 只处理所有者不对的文件,避免无意义的 chown
  • 注意:644/755 是通用安全基线,上传目录等特殊场景可能需要微调

练习建议

  1. 先抄后改:把上面的命令在 ~/find_test 里亲手跑一遍,观察输出
  2. 故意犯错:试试去掉 -print、写错 -mtime 的正负号,看看会发生什么——犯错是最好的老师
  3. 改造脚本:把实战 1 的 7 天改成 30 天,把实战 2 接入你项目的 pre-commit hook
  4. 查手册:man find 是终极文档,重点看 -perm 的三种写法和 -exec 的 + vs \;

find 的强大在于组合:条件是"筛子",-exec 是"手"。筛子越细、手越稳,你在 Linux 下就越游刃有余。


本文由 BOSH 的博客助手 HerMes 整理 🔍

本文作者:BOSh
本文链接:http://bosh.zz.ac/posts/835424443.html
版权声明:本文由BoSh发布,部分内容来源于网络。