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 番目のフィールドを選択します。
  2. |cut コマンドの出力を head コマンドにパイプで送ります。
  3. head -n 3:パイプ入力の最初の 3 行のみを表示します。

この組み合わせにより、ログ エントリの特定の部分に迅速に焦点を当てることができ、調査を効率的に行うことができます。

head と grep を使った調査

次に、head ともう 1 つの強力なコマンドである 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:アクセス ログ ファイル内で "/admin" を含む行を検索します。
  2. |:grep の出力を head コマンドにパイプで送ります。
  3. head -n 3:パイプ入力の最初の 3 行のみを表示します。

この組み合わせにより、ログ ファイル内の関連するエントリに迅速に焦点を当てることができ、調査をより目的的かつ効率的に行うことができます。

head を使った大きなファイルの探索

ファイルの探偵として、非常に大きなログ ファイルに頻繁に遭遇します。head コマンドは、これらのファイルの先頭をすばやく調べるために特に便利で、全体のコンテンツをメモリに読み込まなくて済みます。

これまで使用してきた access.log ファイルを使って、大きなファイルを扱うシミュレーションを行いましょう。実際よりもはるかに大きいと仮定します。

まず、ファイルサイズを確認しましょう。

ls -lh access.log

次に、head を使って最初の 15 行を表示しましょう。

head -n 15 access.log

以前に見たものと同様の出力が表示されるはずですが、10 行ではなく 15 行です。

head コマンドは、非常に大きなファイルを扱う際に特に価値があります。その理由は以下の通りです。

  1. 高速:head はファイルの先頭のみを読み取るため、巨大なファイルでも迅速に完了します。
  2. メモリ効率が良い:head はファイル全体をメモリに読み込む必要がありません。
  3. 迅速なプレビューが得られる:ファイル全体を開かずに、ファイルの構造とコンテンツの概要を把握することができます。

まとめ

この実験では、ファイルの先頭を迅速に調べるための強力なツールである head コマンドを探りました。以下のことを学びました。

  1. デフォルトでは head を使ってファイルの最初の 10 行を表示する。
  2. -n オプションを使って表示する行数をカスタマイズする。
  3. head を使って複数のファイルを同時に調べる。
  4. パイプを使って headcutgrep などの他のコマンドと組み合わせる。
  5. 大きなファイルを効率的に扱うために head を使う。

この実験では扱わなかった追加の head パラメータ:

  • -c:行数ではなく、ファイルの最初の数バイトを表示する。
  • -q:複数のファイルを調べる際にヘッダーを非表示にする。
  • -v:複数のファイルを調べる際に常にヘッダーを表示する。

参考資料