📌 博客原文链接:Breeze

在日常运维中,我们经常面临两个基本需求:“文件在哪?”“如何打包传输?”

找不到文件是 Linux 新手的常见痛点——系统中有成千上万个文件,一个个目录去找?不存在的。本文将全面讲解 whichlocatefind 三大查找工具的使用场景,并深入演示 tar 打包压缩的各种技巧。


文件查找

简介

Linux 提供了多种文件查找工具,各有侧重:

命令 用途 查找对象 特点
which 查找命令位置 可执行命令 PATH 环境变量中搜索
whereis 查找命令位置 命令及其帮助文档 从特定目录快速定位
locate 查找文件 文件名 依赖数据库,速度极快
find 查找文件 文件名、大小、权限、属主等 实时搜索,功能最强大

一、命令文件查找(which)

查找命令的位置

当你想知道某个命令在哪里时,用 which

[root@localhost ~]# which ls
alias ls='ls --color=auto'
	/usr/bin/ls

which 的工作原理:

  • PATH 环境变量定义的目录中依次搜索
  • 找到第一个匹配的可执行文件就返回
# 查看 PATH 环境变量
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

whereis:更全面的命令查找

[root@localhost ~]# whereis   vim
vim: /usr/bin/vim /usr/share/vim /usr/share/man/man1/vim.1.gz

whereis 不仅能找到命令本身,还能找到其帮助文档(man page)和相关配置文件。

which vs whereis 对比

对比项 which whereis
搜索范围 PATH 环境变量 系统特定目录
返回内容 命令路径 命令 + 帮助文档 + 配置
速度 较快 较快
适用场景 查找命令在哪 全面了解命令相关文件

二、locate:快速文件查找

简介

locate 命令通过搜索数据库来查找文件,速度极快,但依赖数据库的更新。

打个比方:

  • find 就像你去图书馆一本一本地翻书来找内容
  • locate 就像你去图书馆查目录卡片,直接告诉你书在哪

实战演示

查找 hosts 文件:

[root@localhost ~]# locate hosts
/etc/hosts
/etc/hosts.allow
/etc/hosts.deny
/usr/share/doc/systemd-219/hosts
/var/lib/sss/mc/hosts

更新 locate 数据库:

[root@localhost ~]# updatedb

重要提示

  • locate 的数据库默认每天更新一次(通过 cron 定时任务)
  • 刚创建的文件,locate 可能找不到,需要先执行 updatedb 更新数据库
  • updatedb 会扫描整个文件系统,可能需要几秒钟

locate 的优缺点

优点 缺点
速度极快(搜索数据库而非磁盘) 数据库更新有延迟
系统开销小 无法按权限、大小等条件查找
适合快速定位文件 无法查找刚创建的文件(需先 updatedb)

三、find:强大的文件查找

简介

find 是 Linux 中最强大的文件查找工具,支持按文件名、大小、属主、属组、文件类型、权限等多种条件进行查找。

语法:

find [路径...] [选项] [表达式] [动作]
│     │       │      │        │
│     │       │      │        └── 找到后做什么(-print, -ls, -delete 等)
│     │       │      └── 查找条件(-name, -size, -user 等)
│     │       └── 额外选项(-maxdepth 等)
│     └── 从哪些目录开始找
└── 命令本身

按文件名查找

# 精确查找(区分大小写)
[root@localhost ~]# find /etc -name "hosts"
/etc/hosts
/etc/avahi/hosts

# 精确查找(忽略大小写)
[root@localhost ~]# find /etc -iname "HOSTS"
/etc/hosts
/etc/avahi/hosts

# 模糊查找(通配符)
[root@localhost ~]# [root@localhost ~]# find /etc -iname "hos*"
/etc/host.conf
/etc/hosts
/etc/hosts.allow
/etc/hosts.deny
/etc/selinux/targeted/active/modules/100/hostname
/etc/hostname
/etc/avahi/hosts
/etc/host.conf
/etc/hosts
/etc/hosts.allow
/etc/hosts.deny
参数 说明
-name 区分大小写
-iname 忽略大小写(i = ignore case)
* 通配符,匹配任意字符

心中有爱,什么都找得到。 熟练掌握 -name 和通配符,就能解决 80% 的查找需求。


按文件大小查找

# 查找大于 5MB 的文件
[root@localhost ~]# find /etc -size +5M

# 查找等于 5MB 的文件
[root@localhost ~]# find /etc -size 5M

# 查找小于 5MB 的文件
[root@localhost ~]# find /etc -size -5M
符号 含义 示例
+ 大于 +5M = 大于 5MB
(无) 等于 5M = 恰好 5MB
- 小于 -5M = 小于 5MB

常用大小单位:

单位 含义
c 字节
k KB
M MB
G GB

指定查找深度

# 最多搜索 4 层目录
[root@localhost ~]# find / -maxdepth 4 -a -name "ifcfg-en*"
/etc/sysconfig/network-scripts/ifcfg-ens33

# 最多搜索 3 层目录(可能找不到)
[root@localhost ~]# find / -maxdepth 3 -a -name "ifcfg-en*"
# 无结果
参数 说明
-maxdepth N 最大搜索深度为 N 层
-mindepth N 最小搜索深度为 N 层
-a 逻辑与(AND),表示同时满足多个条件

目录深度示意:

/                    ← 深度 0
├── etc              ← 深度 1
│   └── sysconfig    ← 深度 2
│       └── network-scripts  ← 深度 3
│           └── ifcfg-ens33  ← 深度 4

按属主、属组查找

# 查找属主是 jack 的文件
[root@localhost ~]# find /home -user jack

# 查找属组是 hr 组的文件
[root@localhost ~]# find /home -group hr

前提:查找的用户和组需要提前创建好。


按文件类型查找

# 查找普通文件
[root@localhost ~]# find /tmp -type f

# 查找块设备文件
[root@localhost ~]# find /dev -type b

# 查找目录
[root@localhost ~]# find / -type d -name "logs"

文件类型代码:

代码 文件类型 说明
f 普通文件(file) 文本文件、二进制文件等
d 目录(directory) 文件夹
b 块设备(block) 磁盘、分区等
c 字符设备(character) 串口、终端等
l 符号链接(link) 软链接文件
p 管道(pipe) 命名管道文件
s 套接字(socket) 进程间通信文件

按文件权限查找

# 查找权限恰好为 644 的文件,并显示详细信息
[root@localhost ~]# find . -perm 644 -ls

# 查找权限为 715 的文件
[root@localhost ~]# find . -perm 715 -print

# 查找至少包含 644 权限的文件(权限掩码)
[root@localhost ~]# find . -perm -644 -ls
参数 说明
-perm 644 权限精确匹配 644
-perm -644 权限至少包含 644(更严格)
-perm /644 权限任意一位匹配即可

找到后的处理动作(Actions)

find 找到文件后,可以执行多种动作:

# 动作 1:显示文件名(默认动作)
[root@localhost ~]# find . -perm 715 -print
./etc/passwd
./etc/shadow

# 动作 2:显示文件详细属性(类似 ls -l)
[root@localhost ~]# find . -perm 715 -ls
12345678    4 -rwxr-xr-x   1 root  root  1024 Jan  1 12:00 ./etc/passwd

# 动作 3:找到后直接删除
[root@localhost ~]# find /etc -name "775*" -delete

# 动作 4:找到后复制(交互式确认)
[root@localhost ~]# find /etc -name "ifcfg*" -ok cp -rvf {} /tmp \;
< cp ... /etc/sysconfig/network-scripts/ifcfg-ens33 > ? y

动作说明:

动作 说明
-print 打印文件名(默认)
-ls 打印文件详细信息(等同 ls -dils
-delete 删除找到的文件(慎用!
-exec 命令 {} \; 对每个文件执行命令
-ok 命令 {} \; -exec,但执行前会提示确认

{}\; 的含义:

  • {} 会被替换为找到的文件名
  • \; 是命令结束标志(分号需要转义)

实战:找到小于 1MB 的文件并移动到 /tmp 目录

[root@localhost ~]# find /var/log -size   -1M -exec mv {} /tmp/ \;

文件打包与压缩

简介

tar 命令是 Unix/Linux 系统中最常用的文件打包工具,几乎可以工作于任何环境中。它的设计初衷是用于备份文件,特别适合针对整个目录进行操作。

打包 vs 压缩:

概念 说明 类比
打包 将多个文件合并成一个文件 把多件衣服放进一个箱子
压缩 使用算法减小文件体积 用真空袋把衣服压紧

tar 本身只做打包,但可以通过 -z-j-J 等参数调用外部压缩工具同时完成压缩。


打包与压缩

基本语法

tar [选项] [压缩包名称] [源文件/目录]

打包(不压缩)

# 将 /etc 目录打包为 etc.tar
[root@localhost ~]# tar -cf etc.tar /etc
参数 说明
-c 创建新归档(create)
-f 指定文件名(file),必须放在最后

打包并压缩

三种压缩格式对比:

# gzip 压缩(速度最快,体积较大)
[root@localhost ~]# tar -czvf etc-gzip.tar.gz /etc/

# bzip2 压缩(速度中等,体积中等)
[root@localhost ~]# tar -cjvf etc-bzip.tar.bz2 /etc/

# xz 压缩(速度最慢,体积最小)
[root@localhost ~]# tar -cJvf etc-xz.tar.xz /etc/

参数说明:

参数 说明
-c 创建新归档
-z 使用 gzip 压缩
-j 使用 bzip2 压缩
-J 使用 xz 压缩(大写 J)
-v 显示详细过程(verbose)
-f 指定文件名

压缩效果对比

[root@localhost ~]# ll -h etc*
-rw-r--r--. 1 root root 9.4M 520 14:39 etc-bzip.tar.bz2
-rw-r--r--. 1 root root  11M 520 14:39 etc-gzip.tar.gz
-rw-r--r--. 1 root root  33M 520 14:39 etc.tar             # 只打包未压缩
-rw-r--r--. 1 root root 7.5M 520 14:39 etc-xz.tar.xz

压缩率对比:

格式 压缩后大小 压缩率 压缩速度 解压速度
gzip 11 MB 约 34% 最快 最快
bzip2 9.4 MB 约 28% 中等 中等
xz 7.5 MB 约 24% 最慢 最慢
未压缩 33 MB 0% - -

结论压缩速度和压缩体积成反比。 追求速度用 gzip,追求体积用 xz。日常使用 gzip 最为普遍。


解压与解包

查看压缩包内容(不解压)

# 查看 tar 包内容
[root@localhost ~]# tar -tf etc.tar
etc/
etc/passwd
etc/shadow
...
参数 说明
-t 列出归档内容(table of contents)
-f 指定文件名

这只是查看,并没有解压


解压压缩包

# 最简单的方式(自动识别压缩格式)
[root@localhost ~]# tar xf etc3.tar.xz

# 解压到指定目录
[root@localhost ~]# tar -xvf etc2.tar.bz2 -C /tmp

# 解压 gzip 压缩包
[root@localhost ~]# tar -xzvf etc-gzip.tar.gz

# 解压 bzip2 压缩包
[root@localhost ~]# tar -xjvf etc-bzip.tar.bz2

# 解压 xz 压缩包
[root@localhost ~]# tar -xJvf etc-xz.tar.xz

参数说明:

参数 说明
-x 解压/解包(extract)
-v 显示详细过程
-f 指定文件名
-C 指定解压目标目录(Change directory)

现代 tar 版本可以自动识别压缩格式,所以 tar xf 就能解压任何格式的压缩包,无需手动指定 -z-j-J。简单粗暴!


实战场景

场景一:备份配置文件

# 备份 /etc 目录
[root@localhost ~]# tar -czvf etc-backup-$(date +%Y%m%d).tar.gz /etc/
[root@localhost ~]# ls
etc-backup-20260520.tar.gz

场景二:迁移数据

# 打包
[root@localhost ~]# tar -czvf project.tar.gz /var/www/html/

# 在目标机器上解压
[root@target ~]# tar -xzvf project.tar.gz -C /var/www/html/

场景三:只解压特定文件

# 先查看压缩包内容
[root@localhost ~]# tar -tf etc-gzip.tar.gz | grep "passwd"
etc/passwd
etc/pam.d/passwd
etc/passwd-
etc/security/opasswd

# 只解压 passwd 文件
[root@localhost ~]# tar -xzvf etc-gzip.tar.gz  etc/passwd
etc/passwd

场景四:追加文件到已有压缩包

# 将新文件追加到已有的 tar 包
[root@localhost ~]# tar -rvf etc.tar /etc/aaa
tar: 从成员名中删除开头的“/”
/etc/aaa/
参数 说明
-r 追加文件到归档末尾

注意-r 只对未压缩的 tar 包有效。压缩后的归档文件不能直接追加。


常见问题

Q1:tar: Removing leading '/' from member names 是什么?

这是 tar 的安全特性。tar 默认会移除绝对路径开头的 /,防止解压时意外覆盖系统文件。

# tar 会自动把 /etc/passwd 变成 etc/passwd
[root@localhost ~]# tar -czvf etc.tar.gz /etc/passwd
tar: Removing leading '/' from member names

# 如果需要保留绝对路径,使用 -P 参数(慎用)
[root@localhost ~]# tar -czPf etc.tar.gz /etc/passwd

Q2:findlocate 应该用哪个?

场景 推荐
快速查找已知文件名 locate
按大小、权限、属主等条件查找 find
查找刚创建的文件 find(或先 updatedb 再用 locate
需要对找到的文件执行操作 find(配合 -exec

Q3:gzipbzip2xz 如何选择?

需求 推荐
日常使用,追求速度 gzip.tar.gz
文件较大,希望更好压缩 bzip2.tar.bz2
归档备份,追求最小体积 xz.tar.xz

Q4:如何统计压缩包中有多少个文件?

[root@localhost ~]# tar -tf etc.tar.gz | wc -l
12345

Q5:find 搜索太慢怎么办?

# 限制搜索深度
find / -maxdepth 3 -name "config"

# 限制只搜索特定类型
find / -type f -name "*.log"

# 排除特定目录
find / -path "/proc" -prune -o -path "/sys" -prune -o -name "myfile" -print

最佳实践

  1. 查找命令优先顺序

    which/whereis → locate → find
    
    • 找命令位置用 which
    • 快速找文件用 locate
    • 精确查找(按大小、权限等)用 find
  2. find + xargs 组合

    # 查找并批量删除
    find /tmp -name "*.tmp" -type f | xargs rm -f
    
    # 查找并统计行数
    find . -name "*.log" | xargs wc -l
    
  3. 打包前先预估大小

    # 查看目录大小
    du -sh /etc/
    # 32M /etc/
    
  4. 压缩包命名规范

    项目名-日期.tar.gz
    示例:backup-20241220.tar.gz
    
  5. 解压前先看内容

    # 先用 -t 查看,确认不会覆盖重要文件
    tar -tf unknown.tar.gz
    # 确认后再解压
    tar -xf unknown.tar.gz -C /safe/dir/
    

总结

通过本文的学习,你应该掌握了:

  • 使用 whichwhereis 查找命令位置
  • 使用 locate 快速搜索文件(配合 updatedb 更新数据库)
  • 使用 find 按文件名、大小、属主、类型、权限等条件查找文件
  • 掌握 find 的各种动作(-print-ls-delete-exec-ok
  • 使用 tar 进行打包和压缩(gzip、bzip2、xz 三种格式)
  • 理解不同压缩格式的速度和体积权衡
  • 掌握解包解压的常用技巧(-C 指定目录、-t 查看内容等)
  • 在实际场景中灵活运用这些工具

学习建议:文件查找和打包压缩是 Linux 运维的基本功。建议在日常操作中刻意练习这些命令,逐渐形成肌肉记忆。特别是 find 命令,条件组合灵活多变,多练多用才能真正掌握。

更多推荐