Linux-Befehl head: Dateianfang anzeigen

LinuxBeginner
Jetzt üben

Einführung

In diesem Lab untersuchen wir den Linux-Befehl head, ein leistungsstarkes Dienstprogramm, mit dem Sie den Anfang von Textdateien schnell anzeigen können. Stellen Sie sich vor, Sie wären ein digitaler Ermittler und müssten zahlreiche Dateien zügig durchsuchen, um wichtige Informationen zu finden. Der Befehl head dient Ihnen dabei als praktische Lupe: Sie können den Dateianfang betrachten, ohne die Dateien vollständig öffnen zu müssen.

Wir simulieren ein Szenario, in dem Sie eine Sammlung von Protokolldateien eines stark ausgelasteten Webservers untersuchen. Ihr Ziel ist es, diese Protokolle effizient zu prüfen, mögliche Probleme zu erkennen und Erkenntnisse zu gewinnen. In dieser praktischen Übung lernen Sie, den Befehl head gezielt einzusetzen, damit die Untersuchung von Dateien schneller und effizienter gelingt.

Grundlagen von head verstehen

In diesem Schritt untersuchen Sie eine einfache Protokolldatei, um die Funktionsweise von head zu verstehen.

Wechseln Sie zunächst in das Projektverzeichnis:

cd /home/labex/project

Verwenden wir nun den Befehl head für eine Datei namens access.log:

head access.log

Die Ausgabe sollte ungefähr so aussehen:

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

Standardmäßig zeigt head die ersten 10 Zeilen einer Datei an. Jede Zeile dieses Protokolls steht für eine einzelne Anfrage an den Webserver und enthält die IP-Adresse, den Zeitstempel, die HTTP-Methode, die angeforderte Ressource, den Statuscode und die Größe der Antwort.

Anzahl der Zeilen anpassen

In diesem Schritt legen Sie fest, wie viele Zeilen head anzeigen soll.

Um nur die ersten 5 Zeilen des Protokolls anzuzeigen, verwenden Sie die Option -n:

head -n 5 access.log

Dieser Befehl sollte folgende Ausgabe erzeugen:

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

Das ist besonders hilfreich, wenn Sie bestimmte Informationen am Anfang einer Datei suchen, aber nicht alle 10 Zeilen anzeigen müssen.

Mehrere Dateien untersuchen

In diesem Schritt verwenden Sie head, um die Dateianfänge mehrerer Dateien gleichzeitig anzuzeigen.

Untersuchen wir die Anfänge von access.log und error.log:

head access.log error.log

Die Ausgabe sollte ungefähr so aussehen:

==> 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/

Beachten Sie, dass head die Ausgaben der einzelnen Dateien durch Überschriften klar voneinander trennt. Das ist besonders nützlich, wenn Sie die Dateianfänge mehrerer Dateien schnell miteinander vergleichen möchten.

head mit Pipes verwenden

In diesem Schritt kombinieren Sie head mithilfe einer Pipe mit einem anderen Befehl.

Angenommen, Sie möchten die ersten 3 Zeilen von access.log anzeigen, aber nur die Teile, die den Zeitstempel und die angeforderte Ressource enthalten. Mit dem Befehl cut in Verbindung mit head gelingt das:

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

Dieser Befehl sollte folgende Ausgabe erzeugen:

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

Der Teil cut -d '"' -f2 access.log teilt jede Zeile an den Anführungszeichen auf und wählt das zweite Feld aus, das die HTTP-Anfrage enthält. Das Zeichen | leitet diese Ausgabe an head -n 3 weiter, das nur die ersten drei Zeilen anzeigt.

Mit dieser Kombination können Sie sich schnell auf bestimmte Bestandteile der Protokolleinträge konzentrieren und die Untersuchung effizienter gestalten.

Mit head und grep ermitteln

In diesem Schritt kombinieren Sie head mit grep, um in der Protokolldatei nach einem bestimmten Muster zu suchen.

Angenommen, es liegen Meldungen über ungewöhnliche Aktivitäten im Zusammenhang mit der Seite /admin vor. Sie möchten die ersten Vorkommen von /admin im Zugriffsprotokoll prüfen:

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

Die Ausgabe sollte ungefähr so aussehen:

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

Der Teil grep "/admin" access.log durchsucht access.log nach Zeilen, die /admin enthalten. Das Zeichen | leitet die passenden Zeilen an head -n 3 weiter, das nur die ersten drei Treffer anzeigt.

Mit dieser Kombination können Sie sich schnell auf relevante Einträge in der Protokolldatei konzentrieren und die Untersuchung gezielter und effizienter durchführen.

Große Dateien mit head untersuchen

In diesem Schritt verwenden Sie head, um eine große Protokolldatei zu untersuchen, ohne ihren gesamten Inhalt in den Arbeitsspeicher zu laden.

Wir simulieren die Arbeit mit einer großen Datei, indem wir die bereits verwendete Datei access.log einsetzen. Dabei tun wir so, als wäre sie wesentlich größer als tatsächlich.

Prüfen wir zunächst die Dateigröße:

ls -lh access.log

Verwenden wir nun head, um die ersten 15 Zeilen anzuzeigen:

head -n 15 access.log

Die Ausgabe sollte der bisherigen ähneln, diesmal jedoch 15 statt 10 Zeilen enthalten.

Der Befehl head ist schnell, weil er nur den Anfang der Datei liest. Außerdem geht er sparsam mit dem Arbeitsspeicher um, da er nicht die gesamte Datei lädt. Dadurch erhalten Sie eine schnelle Übersicht über Aufbau und Inhalt der Datei.

Zusammenfassung

In diesem Lab haben wir den Befehl head kennengelernt, ein leistungsstarkes Werkzeug zur schnellen Untersuchung des Dateianfangs. Wir haben gelernt:

  1. head zu verwenden, um standardmäßig die ersten 10 Zeilen einer Datei anzuzeigen.
  2. Mit der Option -n die Anzahl der angezeigten Zeilen anzupassen.
  3. Mit head mehrere Dateien gleichzeitig zu untersuchen.
  4. head mithilfe von Pipes mit anderen Befehlen wie cut und grep zu kombinieren.
  5. Mit head effizient mit großen Dateien zu arbeiten.

Weitere head-Parameter, die in diesem Lab nicht behandelt wurden:

  • -c: Die ersten Bytes einer Datei statt der ersten Zeilen anzeigen.
  • -q: Beim Untersuchen mehrerer Dateien die Überschriften unterdrücken.
  • -v: Beim Untersuchen mehrerer Dateien immer Überschriften anzeigen.