搜索与数据流:find、grep、管道、重定向

在复杂的文件系统中,寻找特定的配置文件或审计数据是一项硬性挑战。Linux 提供了底层的搜索过滤机制。我们可以通过数据流控制将多个命令串联起来。

文件搜索命令:find

find 能够根据指定的匹配参数,在目录树中进行深度搜索。

  • 按文件名搜索:在指定路径下查找名为 passwords.txt 的文件:
    crow@opsbox:~$ find -name passwords.txt
    ./Storage/passwords.txt
    
  • 使用通配符搜索:使用星号 * 查找当前目录下所有以 .txt 结尾的文件:
    crow@opsbox:~$ find -name "*.txt"
    ./todo.txt
    ./Storage/information.txt
    
  • 多维度条件组合检索: 在实际工作中,我们常需要限定更严格的检索标准。例如:搜索 /etc/ 目录下、类型为文件(-type f)、文件名以 .conf 结尾、且属于 root 用户的所有配置文件。你可以执行:
    crow@opsbox:~$ find /etc/ -type f -name "*.conf" -user root 2>/dev/null
    /etc/resolv.conf
    /etc/sysctl.conf
    

文本检索命令:grep

当你需要在一个或多个文件中检索特定的文本行时,可以使用 grep 命令。

  • 单文件搜索:在 access.log 中查找包含某个 IP 地址的所有记录:
    crow@opsbox:~$ grep "81.143.211.90" access.log
    81.143.211.90 - - [15/May/2020 17:56:29] "GET /index.html HTTP/1.1" 200 -
    
  • 递归搜索:使用 -r-R 选项。它会递归遍历指定文件夹及子主目录中的所有文件:
    crow@opsbox:~$ grep -R "PRETTY_NAME" /etc/
    /etc/os-release:PRETTY_NAME="Ubuntu 22.04.2 LTS"
    
  • 常用 grep 选项
    • -i:忽略大小写。
    • -n:在回显中显示匹配行在文件中的行号。
  • 配合正则表达式使用:正则表达式是文本匹配的强力武器:
    • ^:匹配行首。例如匹配以 root 开头的行:
      crow@opsbox:~$ grep "^root" /etc/passwd
      
    • $:匹配行尾。例如匹配以 /bin/bash 结尾的行:
      crow@opsbox:~$ grep "/bin/bash$" /etc/passwd
      
    • \|:代表逻辑或(OR),配合 -E(支持扩展正则)使用。例如搜索包含 myfalse 的行:
      crow@opsbox:~$ grep -E "(my|false)" /etc/passwd
      sys:x:3:3:sys:/dev:/usr/sbin/nologin
      
    • .*:配合使用可表达逻辑与(AND)。例如,要过滤出同一行中同时依次出现 myfalse 的行:
      crow@opsbox:~$ grep -E "(my.*false)" /etc/passwd
      

数据流与输出重定向

Linux 中的每个进程默认都会自动开启三个文件描述符,代表了三种输入与输出的数据通道:

  • 标准输入(STDIN,文件描述符为 0
  • 标准输出(STDOUT,文件描述符为 1
  • 标准错误(STDERR,文件描述符为 2

为了便于理解数据流与重定向的操作过程,我们可以观察以下逐步递进的命令演示:

1. 默认输入与输出

如果你直接运行 cat 命令且不跟任何文件名,它会等待你的标准输入。你在终端输入一行字并敲回车,cat 会将内容作为标准输出原样打印回屏幕:

crow@opsbox:~$ cat
这里是输入的内容
这里是输入的内容

2. 标准输出与错误的混杂

当我们尝试在包含敏感系统文件的 /etc/ 目录下查找名为 shadow 的文件时:

crow@opsbox:~$ find /etc/ -name shadow
/etc/shadow
find: '/etc/ssl/private': Permission denied

终端屏幕上通常会混杂输出两种数据流:

  • /etc/shadow 是标准输出,代表成功找到的文件。
  • find: '/etc/ssl/private': Permission denied 是标准错误,代表无权访问的报错。

3. 重定向丢弃错误信息

我们可以利用 2> 标记将标准错误(FD 2)重定向写入到 /dev/null 空设备(系统垃圾桶)中。/dev/null 是一个虚拟设备,写入它的任何数据都会被系统丢弃:

crow@opsbox:~$ find /etc/ -name shadow 2>/dev/null
/etc/shadow

执行后,所有的 Permission denied 报错都会被丢弃,屏幕上只会干净地保留正常找出的文件路径。

4. 将成功结果写入文件

我们可以使用 > 覆盖符将标准输出(STDOUT,默认 FD 可省略不写,即 1>)重定向写入一个文件中:

crow@opsbox:~$ find /etc/ -name shadow 2>/dev/null > results.txt

此时,正常的结果会被写入 results.txt,而如果想使用追加写入而不是覆盖,可以使用 >>

crow@opsbox:~$ find /etc/ -name passwd >> results.txt 2>/dev/null

5. 分别重定向输出与错误

我们可以同时控制两种数据流流向不同的文件:

crow@opsbox:~$ find /etc/ -name shadow 2> stderr.txt 1> stdout.txt

6. 整合标准错误与标准输出:2>&1

在管道操作或日志归档中,我们常需要把报错和正常输出合并输出到同一个文件中,可以使用 2>&1(将标准错误重定向至标准输出的副本):

crow@opsbox:~$ find /etc/ -name shadow > results.txt 2>&1

标准输出(1)与标准错误(2)重定向的分流原理流向图

7. 标准输入重定向

使用小于号 < 可以将文件内容作为标准输入传送给命令:

crow@opsbox:~$ cat < stdout.txt
/etc/shadow

8. 输入流引导

我们可以使用 << 并定义一个 EOF 结束标识,输入一段多行文本并存入文件:

crow@opsbox:~$ cat << EOF > stream.txt
寻币安全实验室
每天打卡
EOF

管道操作符与过滤链条

管道 | 用于将前一个命令的标准输出,直接作为后一个命令的标准输入。通过它,我们可以建立强大的多级过滤链条:

管道 | 就像是工厂流水线上的“传送带”(或拼接起来的“水管”)。前一道工序(前一个命令)加工出的半成品数据,不需要落地装箱(保存为临时文件),而是通过传送带(管道)直接送入后一道工序(后一个命令)的加工机器上继续处理。这就实现了高效的链式过滤。

  • 提取并统计:在根目录下搜索所有的 .conf 配置文件,丢弃报错,使用 grep 过滤出包含 systemd 的记录,最后利用 wc -l 统计一共有多少行:
    crow@opsbox:~$ find /etc/ -name "*.conf" 2>/dev/null | grep systemd | wc -l
    12
    

其它控制符

  • 后台异步控制符 &:在命令末尾添加 &,可以使该任务立即进入系统后台运行。
  • 逻辑链操作符 &&:用于顺序执行多条命令(如 cmd1 && cmd2)。只有当 cmd1 执行成功时,cmd2 才会继续运行。

现在,让我们通过下面的练习检验你对这些命令行选项与管道语法的掌握情况。

在终端练习场里练手

模拟实验

在这个终端练习场里跟着敲一遍:用 ls/cd 在目录间移动,用 find 按名字定位文件,用 grep 从输出里筛行,再用 > 和 >> 把结果写进文件。每个动作都做一遍,熟悉命令行的手感。

点击这里启动:

练习一:利用搜索工具定位备份文件

在此实操练习中,我们将学以致用,在真实的 Linux 运维服务器中定位并读取备份文件。

运维人员此前将一份关键的数据库备份文件放在了 /srv/ops 目录之下,其文件名中含有 db 字样。我们需要将其找出来。

首先,打开你的网页终端,此时你已经直接以普通用户 crow 的身份登入系统。

  1. 我们通过 find 命令指定在 /srv/ops 目录下进行检索,使用通配符匹配文件名中含有 db 的项:
    crow@opsbox:~$ find /srv/ops -name '*db*'
    /srv/ops/backups/db-2026-07.sql
    
  2. 我们使用 cat 命令读取这个 SQL 备份文件的内容:
    crow@opsbox:~$ cat /srv/ops/backups/db-2026-07.sql
    -- opsbox nightly dump  2026-07-01
    CREATE TABLE users (id INT, name TEXT);
    INSERT INTO users VALUES (1, 'admin');
    -- backup verify token: COIN{……}
    INSERT INTO users VALUES (2, 'crow');
    
    在数据库的建表和数据插入语句中,找到这行带有校验 Token 的注释。
  3. 记录该令牌并将其提交以完成当前挑战。

读出备份里的校验码

Lab

运维把一份数据库备份落在了 opsbox 的 /srv/ops 目录下,文件名里带 db。备份文件的一条 SQL 注释里写着这次备份的校验码。

打开你的网页终端(TARGET 终端(启动 Lab 后显示),你已经是 crow 用户),把这个文件找出来、读出注释里的校验码并提交。

提交格式:COIN{........}(8 位大写十六进制)。

加载会话状态…

提交 coin

题解 Hint