Command-line POST requests enable direct interaction with HTTP endpoints, replaying web form submissions and driving small automation tasks without relying on a browser. The wget utility, commonly installed on many Linux systems, can issue POST requests in addition to its usual download and mirroring capabilities.

By default, wget sends HTTP GET requests and writes response bodies to files on disk. POST support is enabled through the –post-data option for short inline payloads and –post-file for bodies read from disk, combined with optional –header directives to set Content-Type and –output-document to control where the response is stored. Response headers and status codes remain visible through –server-response, which prints the HTTP exchange directly to the terminal.

Correct quoting of POST data is essential, especially for JSON payloads and characters such as ampersands, quotes, and equals signs that have special meaning to the shell. Inline payloads placed in –post-data are visible in process listings and shell history, so sensitive information such as API keys or credentials is safer in a body file used with –post-file instead. The examples below assume a POSIX-compatible shell such as bash with outbound HTTPS access to a public echo service, but the wget options shown behave the same way on other platforms.

Steps to send POST data with wget:

  1. Send a form-encoded POST request to an echo endpoint while saving the response body to a local file for inspection.
    $ wget --quiet \
      --output-document=post-form.html \
      --header='Content-Type: application/x-www-form-urlencoded' \
      --post-data='name=alice&role=admin' \
      https://httpbin.org/post
     
    $ head -n 12 post-form.html
    {
      "args": {},
      "data": "",
      "files": {},
      "form": {
        "name": "alice",
        "role": "admin"
      },
    ##### snipped #####

    Echo endpoints such as https://httpbin.org mirror submitted fields in a JSON document, which provides an immediate check that the expected form parameters reached the server.

  2. Submit a JSON POST body using an inline payload and a matching Content-Type header.
    $ wget --quiet \
      --output-document=post-json.html \
      --header='Content-Type: application/json' \
      --post-data='{"name":"alice","role":"admin"}' \
      https://httpbin.org/post
     
    $ grep -n '"json"' post-json.html | head -n 4
    12:  "json": {
    13:    "name": "alice",
    14:    "role": "admin"
    ##### snipped #####

    Inline JSON in –post-data appears in process listings and shell history, so secrets such as API tokens and passwords should not be embedded directly in the command line on shared systems.

  3. Store a larger or sensitive JSON payload in a body file and send it with –post-file to keep it out of the shell command line.
    $ cat >body.json <<'EOF'
    {
      "name": "alice",
      "role": "admin",
      "tags": ["cli", "wget", "post"]
    }
    EOF
     
    $ wget --quiet \
      --output-document=post-file.html \
      --header='Content-Type: application/json' \
      --post-file=body.json \
      https://httpbin.org/post
     
    $ grep -n '"tags"' post-file.html
    21:    "tags": [
    22:      "cli",
    23:      "wget",
    24:      "post"
    ##### snipped #####

    –post-file reads the request body directly from disk, which keeps long or sensitive payloads out of both process listings and shell history while still allowing reuse across multiple POST calls.

  4. Check the HTTP status code for a POST request by printing server response headers to the terminal.
    $ wget --server-response \
      --output-document=/dev/null \
      --header='Content-Type: application/json' \
      --post-data='{"ping":"ok"}' \
      https://httpbin.org/post 2>&1 | grep HTTP/
      HTTP/1.1 200 OK
    ##### snipped #####

    A successful POST normally returns an HTTP 2xx status such as 200 OK, while 4xx and 5xx codes indicate client or server side errors that require further inspection.

  5. Remove temporary files created during testing when they are no longer required.
    $ rm --force post-form.html post-json.html post-file.html body.json

    Deleting test files avoids leaving payloads on disk that might include real tokens, personal data, or other sensitive information copied from production requests.

Discuss the article:

Comment anonymously. Login not required.