Linux head 命令:文件开头显示

LinuxLinuxBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,我们将探索 Linux 中的 head 命令,这是一个用于预览文本文件开头的强大工具。想象一下,你是一名数字侦探,任务是从大量文件中快速扫描以找到关键信息。head 命令将成为你可靠的放大镜,让你无需完全打开文件即可查看文件的开头部分。

我们将模拟一个场景,在这个场景中,你正在调查来自一个繁忙的 Web 服务器的日志文件集合。你的目标是高效地检查这些日志,以识别潜在问题并收集见解。通过这个实践练习,你将学习如何有效地使用 head 命令,使你的文件探索任务更快、更高效。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) linux(("Linux")) -.-> linux/TextProcessingGroup(["Text Processing"]) linux/BasicFileOperationsGroup -.-> linux/ls("Content Listing") linux/BasicFileOperationsGroup -.-> linux/head("File Beginning Display") linux/TextProcessingGroup -.-> linux/grep("Pattern Searching") subgraph Lab Skills linux/ls -.-> lab-214302{{"Linux head 命令:文件开头显示"}} linux/head -.-> lab-214302{{"Linux head 命令:文件开头显示"}} linux/grep -.-> lab-214302{{"Linux head 命令:文件开头显示"}} end

理解 head 的基础知识

让我们从一个简单的日志文件开始,了解 head 的工作原理。

首先,导航到项目目录:

cd /home/labex/project

现在,让我们对名为 access.log 的文件使用 head 命令:

head access.log

你应该会看到类似以下的输出:

192.168.1.100 - - [01/Jan/2024:00:00:01 +0000] "GET /index.html HTTP/1.1" 200 1234
192.168.1.101 - - [01/Jan/2024:00:00:02 +0000] "GET /style.css HTTP/1.1" 200 567
192.168.1.102 - - [01/Jan/2024:00:00:03 +0000] "GET /logo.png HTTP/1.1" 200 2345
192.168.1.103 - - [01/Jan/2024:00:00:04 +0000] "POST /login HTTP/1.1" 302 -
192.168.1.104 - - [01/Jan/2024:00:00:05 +0000] "GET /dashboard HTTP/1.1" 200 3456
192.168.1.105 - - [01/Jan/2024:00:00:06 +0000] "GET /api/user HTTP/1.1" 200 789
192.168.1.106 - - [01/Jan/2024:00:00:07 +0000] "GET /images/banner.jpg HTTP/1.1" 200 4567
192.168.1.107 - - [01/Jan/2024:00:00:08 +0000] "POST /comment HTTP/1.1" 201 -
192.168.1.108 - - [01/Jan/2024:00:00:09 +0000] "GET /search?q=linux HTTP/1.1" 200 2345
192.168.1.109 - - [01/Jan/2024:00:00:10 +0000] "GET /about HTTP/1.1" 200 1234

默认情况下,head 会显示文件的前 10 行。日志中的每一行代表对 Web 服务器的一次请求,显示了 IP 地址、时间戳、HTTP 方法、请求的资源、状态码和响应大小。

自定义显示的行数

有时,10 行可能太多或太少。让我们学习如何自定义 head 显示的行数。

要仅查看日志的前 5 行,可以使用 -n 选项:

head -n 5 access.log

该命令的输出应为:

192.168.1.100 - - [01/Jan/2024:00:00:01 +0000] "GET /index.html HTTP/1.1" 200 1234
192.168.1.101 - - [01/Jan/2024:00:00:02 +0000] "GET /style.css HTTP/1.1" 200 567
192.168.1.102 - - [01/Jan/2024:00:00:03 +0000] "GET /logo.png HTTP/1.1" 200 2345
192.168.1.103 - - [01/Jan/2024:00:00:04 +0000] "POST /login HTTP/1.1" 302 -
192.168.1.104 - - [01/Jan/2024:00:00:05 +0000] "GET /dashboard HTTP/1.1" 200 3456

当你需要在文件开头附近查找特定信息但不需要查看所有 10 行时,这尤其有用。

检查多个文件

作为一名文件侦探,你经常需要快速查看多个文件。head 命令允许你同时查看多个文件的开头部分。

让我们同时查看 access.logerror.log 的开头:

head access.log error.log

你应该会看到类似以下的输出:

==> access.log <==
192.168.1.120 - - [01/Jan/2024:00:00:53 +0000] "POST /about HTTP/1.1" 200 7616
192.168.1.147 - - [01/Jan/2024:00:00:45 +0000] "GET /dashboard HTTP/1.1" 200 7348
192.168.1.138 - - [01/Jan/2024:00:00:03 +0000] "DELETE /comment HTTP/1.1" 400 8341
192.168.1.138 - - [01/Jan/2024:00:00:31 +0000] "DELETE /about HTTP/1.1" 200 3254
192.168.1.122 - - [01/Jan/2024:00:00:15 +0000] "PUT /index.html HTTP/1.1" 500 6061
192.168.1.125 - - [01/Jan/2024:00:00:09 +0000] "DELETE /logo.png HTTP/1.1" 301 4916
192.168.1.148 - - [01/Jan/2024:00:00:33 +0000] "POST /admin/dashboard HTTP/1.1" 201 5546
192.168.1.146 - - [01/Jan/2024:00:00:56 +0000] "GET /images/banner.jpg HTTP/1.1" 301 2332
192.168.1.195 - - [01/Jan/2024:00:00:12 +0000] "DELETE /dashboard HTTP/1.1" 404 6740
192.168.1.136 - - [01/Jan/2024:00:00:18 +0000] "GET /login HTTP/1.1" 200 2374

==> error.log <==
[01/Jan/2024:00:01:23 +0000] [error] [client 192.168.1.150] File does not exist: /var/www/html/missing.html
[01/Jan/2024:00:02:34 +0000] [error] [client 192.168.1.151] PHP Parse error:  syntax error, unexpected ';' in /var/www/html/index.php on line 30
[01/Jan/2024:00:03:45 +0000] [warn] [client 192.168.1.152] ModSecurity: Access denied with code 403 (phase 2). Matched phrase "sql injection attempt" at REQUEST_URI. [file "/etc/modsecurity/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "50"] [id "942100"] [rev ""] [msg "SQL Injection Attack Detected via libinjection"] [data "Matched Data: SQL injection found within REQUEST_URI: /vulnerable.php?id=1'"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [hostname "example.com"] [uri "/vulnerable.php"] [unique_id "YvKp2H8AAQEAAAxxBGIAAAAC"]
[01/Jan/2024:00:04:56 +0000] [error] [client 192.168.1.153] AH01071: Got error 'PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function mysql_connect() in /var/www/html/db.php:15...'
[01/Jan/2024:00:05:67 +0000] [warn] [client 192.168.1.154] ModSecurity: Warning. Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file "/etc/modsecurity/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "57"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [hostname "example.com"] [uri "/admin"] [unique_id "YvKp2H8AAQEAAAxxBGIAAAAD"]
[01/Jan/2024:00:06:78 +0000] [error] [client 192.168.1.155] PCE: Can't open perl script "/var/www/html/cgi-bin/printenv": No such file or directory
[01/Jan/2024:00:07:89 +0000] [warn] [client 192.168.1.156] ModSecurity: Access denied with code 403 (phase 2). Matched phrase "directory traversal attempt" at ARGS:file. [file "/etc/modsecurity/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "75"] [id "930110"] [rev ""] [msg "Path Traversal Attack (/../)"] [data "Matched Data: ../ found within ARGS:file: ../../../etc/passwd"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [hostname "example.com"] [uri "/download.php"] [unique_id "YvKp2H8AAQEAAAxxBGIAAAAE"]
[01/Jan/2024:00:08:90 +0000] [error] [client 192.168.1.157] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /var/www/html/memory_hog.php on line 10
[01/Jan/2024:00:09:01 +0000] [warn] [client 192.168.1.158] ModSecurity: Warning. Pattern match "(?i:(?:[\s'\"`_''\(\)]*?(?:[\d\w]+[\s'\"`_''\(\)]*?){2,}[\s'\"`_''\(\)]*?(?:having|rongjitest|select|union|where|get_lst))" at ARGS:username. [file "/etc/modsecurity/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "1126"] [id "942480"] [rev ""] [msg "SQL Injection Attack"] [data "Matched Data: union select found within ARGS:username: admin' UNION SELECT password FROM users--"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [hostname "example.com"] [uri "/login.php"] [unique_id "YvKp2H8AAQEAAAxxBGIAAAAF"]
[01/Jan/2024:00:10:12 +0000] [error] [client 192.168.1.159] AH01797: client denied by server configuration: /var/www/html/restricted/

注意 head 如何通过标题清晰地分隔每个文件的输出。当你需要快速比较多个文件的开头时,这非常有用。

结合管道使用 head

作为一名熟练的文件侦探,你经常需要结合多个命令来更有效地过滤和分析数据。head 命令与管道配合得很好,允许你将其与其他命令串联使用。

假设你想查看 access.log 的前 3 行,但只显示时间戳和请求的资源部分。你可以使用 cut 命令与 head 命令结合来实现这一点:

cut -d '"' -f2 access.log | head -n 3

该命令的输出应为:

POST /about HTTP/1.1
GET /dashboard HTTP/1.1
DELETE /comment HTTP/1.1

以下是该命令的作用:

  1. cut -d '"' -f2 access.log:将每一行按引号分割,并选择第二个字段,其中包含 HTTP 请求。
  2. |:将 cut 命令的输出通过管道传递给 head 命令。
  3. head -n 3:仅显示管道输入的前 3 行。

这种组合使你可以快速聚焦于日志条目的特定部分,从而提高调查效率。

结合 headgrep 进行调查

现在,让我们将 head 与另一个强大的命令 grep 结合使用,以在日志中搜索特定模式。

假设你收到了与 /admin 页面相关的异常活动报告。你想检查访问日志中前几次出现的 /admin

grep "/admin" access.log | head -n 3

该命令的输出可能类似于:

192.168.1.148 - - [01/Jan/2024:00:00:33 +0000] "POST /admin/dashboard HTTP/1.1" 201 5546
192.168.1.115 - - [01/Jan/2024:00:00:22 +0000] "PUT /admin HTTP/1.1" 302 1113
192.168.1.163 - - [01/Jan/2024:00:00:56 +0000] "POST /admin/dashboard HTTP/1.1" 301 815

该命令的作用如下:

  1. grep "/admin" access.log:在 access.log 文件中搜索包含 /admin 的行。
  2. |:将 grep 的输出通过管道传递给 head 命令。
  3. head -n 3:仅显示管道输入的前 3 行。

这种组合使你可以快速聚焦于日志文件中的相关条目,从而使你的调查更具针对性和效率。

使用 head 探索大文件

作为一名文件侦探,你经常会遇到非常大的日志文件。head 命令特别适合快速查看这些文件的开头部分,而无需将整个内容加载到内存中。

让我们通过使用我们一直在处理的 access.log 文件来模拟处理大文件的情况。我们将假装它比实际大小要大得多。

首先,让我们检查文件大小:

ls -lh access.log

现在,让我们使用 head 查看前 15 行:

head -n 15 access.log

你应该会看到类似于我们之前看到的输出,但这次是 15 行而不是 10 行。

head 命令在处理非常大的文件时尤其有价值,因为:

  1. 它速度快:head 只读取文件的开头部分,因此即使对于巨大的文件,它也能快速完成。
  2. 它内存效率高:head 不需要将整个文件加载到内存中。
  3. 它提供快速预览:你可以在不打开整个文件的情况下了解文件的结构和内容。

总结

在本实验中,我们探索了 head 命令,这是一个用于快速查看文件开头的强大工具。我们学习了如何:

  1. 使用 head 默认查看文件的前 10 行。
  2. 使用 -n 选项自定义显示的行数。
  3. 使用 head 同时检查多个文件。
  4. 通过管道将 headcutgrep 等其他命令结合使用。
  5. 使用 head 高效处理大文件。

本实验未涵盖的其他 head 参数:

  • -c:显示文件的前几个字节而不是行。
  • -q:在检查多个文件时隐藏标题。
  • -v:在检查多个文件时始终显示标题。

资源