curl-Befehl: Optionen, POST-Anfragen und Dateien herunterladen
Der curl-Befehl ist ein Werkzeug, das vom Terminal aus eine Anfrage an eine Webadresse sendet und die Antwort unverändert ausgibt. Mit einer einzigen Zeile prüfst du den Seiteninhalt, die Header und den Statuscode. Als wir von einem AlmaLinux-9-Server aus curl-Anfragen an eine WordPress-Website schickten, verwies die http-Adresse mit einer 301-Antwort auf die https-Adresse, und eine REST-API-Anfrage ohne Authentifizierung wurde mit 401 abgelehnt.
1️⃣ Grundlegende Verwendung des curl-Befehls und der Antwortinhalt
Hängst du eine Adresse an curl an, sendet curl eine GET-Anfrage an diese Adresse und gibt den Antwortinhalt auf dem Bildschirm aus. Als wir die von WordPress erzeugte robots.txt anfragten, kam der Inhalt der dreizeiligen Datei unverändert zurück.
curl https://example.com/robots.txtUser-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.phpMan erwartet leicht dieselbe Seite wie nach der Eingabe der Adresse im Browser, doch curl gibt das rohe HTML aus, das der Server geschickt hat. curl führt keine Skripte aus und fordert Bilder und CSS nicht gesondert an. Seiten-HTML ist lang, deshalb leiten wir die Ausgabe bei Webseiten-Adressen per Pipe an head weiter und prüfen nur die ersten Zeilen.
curl -s https://example.com/ | head -n 2<!DOCTYPE html>
<html lang="ko-KR">Mit -s wird die Fortschrittsanzeige ausgeblendet, die sich beim Weiterleiten per Pipe sonst in die Ausgabe mischt. Das HTML, das allein von der Adresse der Startseite kam, war 96.679 Byte groß. Bild- und Skriptdateien sind in dieser Größe nicht enthalten.
2️⃣ Header mit curl -I prüfen und Weiterleitungen mit -L folgen
Am Inhalt allein erkennst du nicht, ob die Anfrage erfolgreich war, deshalb prüfst du Statuscode und Header getrennt mit -I. -I sendet eine HEAD-Anfrage und gibt nur die Antwort-Header ohne Inhalt aus. Das ist so, als würdest du nur den Versandschein lesen, ohne das Paket zu öffnen.
curl -I https://example.com/HTTP/2 200
server: nginx/1.28.0
date: Wed, 28 Oct 2026 05:29:23 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
last-modified: Tue, 27 Oct 2026 21:12:18 GMT
cache-control: max-age=0
expires: Wed, 28 Oct 2026 05:29:23 GMT
accept-ranges: none
alt-svc: h3=":443"; ma=86400Das [HTTP/2 200] in der ersten Zeile ist der Statuscode. Darunter folgen Servertyp, Inhaltstyp und Cache-Header. Sendest du dieselbe Anfrage an die http-Adresse, erscheint 301 zusammen mit der https-Zieladresse im Header [Location].
curl -I http://example.com/HTTP/1.1 301 Moved Permanently
Server: nginx/1.28.0
Date: Wed, 28 Oct 2026 05:27:51 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://example.com/Als wir die http-Adresse ohne Optionen anfragten, fragte curl die Adresse aus [Location] nicht erneut an, sondern gab nur die 7 Zeilen Inhalt der 301-Antwort aus und beendete sich.
curl http://example.com/<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>Mit -L fragt curl die Adresse aus [Location] erneut an. Kombinierst du es mit -I zu -IL, folgen auf die Header der 301-Antwort der Reihe nach die Header der 200-Antwort.
curl -IL http://example.com/HTTP/1.1 301 Moved Permanently
Server: nginx/1.28.0
Date: Wed, 28 Oct 2026 05:29:23 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://example.com/
HTTP/2 200
server: nginx/1.28.0
date: Wed, 28 Oct 2026 05:29:23 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
last-modified: Tue, 27 Oct 2026 21:12:18 GMT
cache-control: max-age=0
expires: Wed, 28 Oct 2026 05:29:23 GMT
accept-ranges: none
alt-svc: h3=":443"; ma=86400Im Diagramm unten kannst du Schritt für Schritt vergleichen, wie viele Anfragen je nach Option hinausgehen und was auf dem Bildschirm erscheint.
3️⃣ Dateien mit dem curl-Befehl herunterladen (-o, -O)
-O speichert die Datei unter dem letzten Dateinamen der Adresse im aktuellen Ordner. Während des Speicherns zeigt der Bildschirm statt des Inhalts eine Fortschrittsanzeige.
curl -O https://example.com/wp-includes/images/w-logo-blue.png % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 3113 100 3113 0 0 178k 0 --:--:-- --:--:-- --:--:-- 190kls -l w-logo-blue.png-rw-r--r-- 1 root root 3113 Oct 28 14:29 w-logo-blue.pngNach dem Herunterladen zeigten [Total] und [Received] in der Fortschrittsanzeige beide 3113, und die mit ls -l geprüfte Dateigröße stimmte mit 3.113 Byte überein.
Willst du den Dateinamen selbst festlegen, schreibst du ihn hinter -o. Unten siehst du das Ergebnis, wenn die Adresse der Startseite als home.html gespeichert wird.
curl -o home.html https://example.com/ % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 96679 0 96679 0 0 4291k 0 --:--:-- --:--:-- --:--:-- 4291kls -l home.html-rw-r--r-- 1 root root 96679 Oct 28 14:29 home.html-O übernimmt den Dateinamen am Ende der Adresse unverändert und passt daher nicht zu Seitenadressen, die mit einem Schrägstrich enden. Hängst du -O an die Adresse der Startseite, findet curl keinen Dateinamen und bricht mit dem Fehler unten ab.
curl -O https://example.com/curl: Remote file name has no length!
curl: (23) Failed writing received data to disk/application4️⃣ POST-Anfragen mit curl und JSON-Daten senden
Um mit einer Anfrage, die bisher nur gelesen hat, Daten mitzuschicken, verwendest du -d, und mit -H gibst du das Datenformat an. -d sendet die dahinter geschriebenen Daten als POST-Inhalt. Ohne weitere Angabe ist der [Content-Type] [application/x-www-form-urlencoded].
Mit -d wird die Anfragemethode zu POST, deshalb kannst du [-X POST] weglassen. Auch die offizielle Dokumentation erklärt, dass -X meist nicht nötig ist.
Wenn du JSON sendest, änderst du mit -H den [Content-Type] auf [application/json]. Unten siehst du das Ergebnis einer Anfrage zum Erstellen eines Beitrags an die WordPress-REST-API ohne Authentifizierung.
curl -s -X POST -H 'Content-Type: application/json' -d '{"title":"curl test"}' https://example.com/wp-json/wp/v2/posts{"code":"rest_authentication_error","message":"\uc8c4\uc1a1\ud569\ub2c8\ub2e4. REST API \uc694\uccad\uc744 \ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.","data":{"status":401}}Die angefragte Website blockiert REST-API-Anfragen von nicht angemeldeten Nutzern und daher kam bei code [rest_authentication_error] zurück, der Status war 401. Wegen derselben Einstellung kam auch bei einer GET-Anfrage nach der Beitragsliste an derselben Adresse 401 zurück. Der Wert von message ist eine Fehlermeldung in der Sprache der Website, die in die Unicode-Schreibweise von JSON umgewandelt wurde.
Um nur den Statuscode zu prüfen, verwirfst du den Inhalt mit [-o /dev/null] und gibst mit -w nur http_code aus.
curl -s -o /dev/null -w '%{http_code}\n' -X POST -H 'Content-Type: application/json' -d '{"title":"curl test"}' https://example.com/wp-json/wp/v2/posts4015️⃣ Antwortzeit mit dem curl-Befehl messen (-w)
Bei langsamen Antworten schaut man leicht nur auf total, aber ob die Zeit beim Verbindungsaufbau oder bei der Verarbeitung auf dem Server verloren ging, siehst du erst, wenn du die Zeiten der einzelnen Abschnitte getrennt ausgibst. -w gibt nach Ende der Anfrage die Messwerte im angegebenen Format aus. Die Werte werden an den Stellen [%{Variablenname}] im Format eingesetzt.
Den Inhalt verwirfst du mit [-o /dev/null], die Fortschrittsanzeige blendest du mit -s aus.
curl -o /dev/null -s -w 'code: %{http_code}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\n' https://example.com/code: 200
connect: 0.001507
tls: 0.017728
ttfb: 0.021912
total: 0.022825connect ist der TCP-Verbindungsaufbau, tls die TLS-Aushandlung, ttfb die Zeit bis kurz vor der Übertragung des ersten Bytes und total die Zeit bis zum Ende der Übertragung. Alle vier Werte sind in Sekunden ab dem Start der Anfrage aufsummiert.
Da der Server, auf dem curl lief, und die angefragte Website auf demselben Server lagen, dauerte der Verbindungsaufbau nur 0,0015 Sekunden, bis zum Ende der TLS-Aushandlung vergingen 0,0177 Sekunden und bis zum ersten Byte 0,0219 Sekunden. Vom Ende der TLS-Aushandlung bis zum Eintreffen des ersten Bytes waren es etwa 0,004 Sekunden. Laut offizieller Dokumentation enthält dieser Abschnitt die Zeit, die der Server zum Erzeugen des Ergebnisses braucht.
Als wir denselben Befehl noch dreimal ausführten, lag total zwischen 0,0219 und 0,0226 Sekunden.
🔲 Simulator für den curl-Befehl
Im Simulator unten kannst du die bisherigen Befehle selbst eingeben und prüfen, wie sich die Ausgabe je nach Option ändert.
🔢 FAQ & empfohlene Inhalte








ℹ️ Affiliate-Hinweis
Die Inhalte dieser Website enthalten Affiliate-Links. Kauft ein Besucher über einen dieser Links ein Produkt oder eine Dienstleistung, erhält die Website vom Verkäufer eine Provision. Der Betrag, den der Käufer zahlt(bei Aktionsrabatten sinkt er ↓), steigt dadurch nicht. Angegebene Preise, Rabatte und Lagerbestände entsprechen dem Stand bei Erstellung und können abweichen; prüfe sie daher vor dem Kauf beim Verkäufer. Produkte werden nach eigenen Kriterien ausgewählt und bewertet, und Provisionen beeinflussen weder die Reihenfolge noch den Inhalt der Bewertungen.