Linux

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > Linux > Linux之curl命令

Linux之curl命令的使用及说明

作者:fengyehongWorld

本文详细介绍了如何使用curl命令行工具进行各种HTTP请求,包括GET、POST、文件上传等操作,同时,也讲述了curl的常用参数和选项,如请求方式、数据提交方式、头部信息、输出控制等,此外,还探讨了提交数据的常见格式,如URL参数、表单提交、JSON和XML数据等

一. 前期准备

1.1 curl命令简介

curl 是一个强大的命令行工具,用于向服务器发送请求并获取数据。

它支持多种协议(如 HTTP、HTTPS、FTP、SFTP 等),常用于接口测试、下载文件、提交表单等操作。

命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。

除了curl命令之外,类似的还有HTTPie命令。

项目curlHTTPie
命令名curlhttp
默认预装✅ Linux 预装❌ 需手动安装
所属语言C 编写(高性能)Python 编写(易扩展)
依赖情况几乎无依赖依赖 Python 环境
支持协议HTTP, HTTPS, FTP, SFTP, SCP, SMTP 等仅支持 HTTP 和 HTTPS

1.2 环境准备

截止到2025年7月31日,curl的最新版本为8.15.0,由于linux系统预装的并不是最新版本的curl命令,此处介绍下载curl源码的方式,编译安装。笔者使用的是如下版本的Ubuntu系统。

apluser@FengYeHong-HP:work$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

1.2.1 安装源码编译依赖库

sudo apt update
sudo apt install -y build-essential libssl-dev libnghttp2-dev libz-dev libidn2-dev libpsl-dev
库名作用用途
build-essential安装构建 C/C++ 程序所需的基础工具,
包含了 gcc, g++, make 以及其他常用构建工具。
几乎所有需要编译源代码的软件都会依赖它。
libssl-devOpenSSL 的开发库。支持使用 HTTPS, TLS/SSL 等安全协议的程序开发,
比如 curl、wget、openssl 自己等。
libnghttp2-devHTTP/2 协议支持库的开发包。为支持 HTTP/2 的网络程序提供功能,
如新版 curl、nginx、httpie 等。
libz-devzlib 的开发包(压缩库)。支持 gzip/deflate 等压缩算法,
是许多程序处理压缩数据(如 HTTP 请求)时所需的库。
libidn2-dev用于国际化域名(IDN)的解析(支持非 ASCII 域名)。使网络工具能识别形如 https://你好.中国 这种 URL。
libpsl-devPublic Suffix List 的开发包。在处理域名时帮助判断顶级域(如 .com.cn 是一个后缀),用于 cookie 安全处理等。

1.2.2 下载并编译安装最新的curl

下载最新的curl安装包

echo "8.15.0" | xargs -I {} curl -LO https://curl.se/download/curl-{}.tar.gz
tar -xzf curl-8.7.1.tar.gz
cd curl-8.7.1
./configure --with-ssl
make -j$(nproc)
sudo make install

1.2.3 版本确认

编译安装之后,确认curl命令的最新版本,然而此时的版本显示为旧版本

apluser@FengYeHong-HP:curl-8.15.0$ curl --version
curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.13
Release-Date: 2022-01-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets zstd
apluser@FengYeHong-HP:curl-8.15.0$

编译安装的 curl 默认路径是 /usr/local/bin/curl,可能和系统原本/usr/bin/curl冲突,你可以通过以下方式优先使用新的版本

# 清除旧路径缓存
apluser@FengYeHong-HP:curl-8.15.0$ hash -r
# 查看curl命令的最新路径
apluser@FengYeHong-HP:curl-8.15.0$ which curl
/usr/local/bin/curl

再次确认curl版本,会发现提示报错,出现此错误的原因是

apluser@FengYeHong-HP:curl-8.15.0$ curl --version
curl: symbol lookup error: curl: undefined symbol: curl_easy_header
apluser@FengYeHong-HP:curl-8.15.0$

1.2.4 添加动态库链接路径

确保系统永久识别新版本 libcurl

# 1. 确认新版本 libcurl 已安装到 /usr/local/lib
ls /usr/local/lib | grep libcurl
# 2. 添加 /usr/local/lib 到动态库搜索路径
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/local-curl.conf
# 3. 让系统重新加载动态链接器缓存
sudo ldconfig

然后就可以发现,curl的版本为最新的了

apluser@FengYeHong-HP:~$ which curl
/usr/local/bin/curl
apluser@FengYeHong-HP:~$ curl --version
curl 8.15.0 (x86_64-pc-linux-gnu) libcurl/8.15.0 OpenSSL/3.0.2 zlib/1.2.11 libidn2/2.3.2 libpsl/0.21.0 nghttp2/1.43.0
Release-Date: 2025-07-16
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS HSTS HTTP2 HTTPS-proxy IDN IPv6 Largefile libz NTLM PSL SSL threadsafe TLS-SRP UnixSockets

1.3 Springboot接口准备

1.3.1 get接口

@GetMapping("/get")
@ResponseBody
public ResponseEntity<Map> getCurl(
        @RequestParam(value = "JobId", required = false) String jobId
        , @RequestParam(value = "INFILE", required = false) String inFilePath
        , @RequestParam(value = "OTFILE", required = false) String outFilePath
        , @RequestParam(value = "name", required = false) String name
) {

    Map<Object, Object> map = new HashMap<>() {{
        put("id", 110120);
        put("name", "枫叶红");
    }};
    return ResponseEntity.ok(map);
}

1.3.2 Post接口

1.3.2.1 from
@Data
public class Test36Form {

    private String order_id;
    private String event;
}

@PostMapping("/form/post")
public ResponseEntity<Map<String, String>> formPostCurl(Test36Form curlForm) {

     System.out.println(curlForm);

     Map<String, String> map = new HashMap<>() {{
         put("type", "form请求");
         put("result", "成功");
     }};
     return ResponseEntity.ok(map);
 }
1.3.2.2 json
@PostMapping("/json/post")
public ResponseEntity<Map<String, String>> jsonPostCurl(
        @RequestHeader(value = "X-TOKEN", required = false) String xToken,
        @RequestBody Map<String, Object> mapData
) {

    System.out.println(mapData);
    System.out.println("接收到的token请求头为: " + xToken);

    Map<String, String> map = new HashMap<>() {{
        put("type", "json请求");
        put("result", "成功");
    }};
    return ResponseEntity.ok(map);
}

1.3.3 文件上传

1.3.3.1 表单提交
@PostMapping("/file/upload")
public ResponseEntity<Map<String, String>> fileUploadCurl(MultipartHttpServletRequest request) {

    // 获取curl命令上传的文件
    MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
    List<MultipartFile> file1 = multiFileMap.get("file1");
    // 获取上传的文件名称
    System.out.println(file1.get(0).getOriginalFilename());

    // 获取curl文提交的数据
    Map<String, String[]> parameterMap = request.getParameterMap();

    String[] params1 = parameterMap.get("jsonData1");
    System.out.println(Arrays.toString(params1));

    String[] params2 = parameterMap.get("jsonData2");
    System.out.println(Arrays.toString(params2));

    Map<String, String> map = new HashMap<>() {{
        put("type", "文件上传请求");
        put("result", "成功");
    }};
    return ResponseEntity.ok(map);
}
1.3.3.2 Put文件上传
@PutMapping("/put/file")
public ResponseEntity<Map<String, String>> putFile(HttpServletRequest request) throws IOException {

    // 获取请求头中的包含的上传文件名称
    String fileName = request.getHeader("X-Filename");
    System.out.println("上传的文件名称为: " + fileName);
    
    // 获取上传的文件输入流
    InputStream inputStream = request.getInputStream();

    // 文件保存
    Path filePath = Paths.get(fileName);
    Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);

    Map<String, String> map = new HashMap<>() {{
        put("type", "文件上传请求");
        put("result", "成功");
    }};
    return ResponseEntity.ok(map);
}

二. 常用参数

2.1 请求方式相关

2.1.1-G⇔--get发送Get请求

发送Get请求

apluser@FengYeHong-HP:~$ curl -G -w '\n' 'http://192.168.3.24:9002/curl/get'
{"name":"枫叶红","id":110120}
apluser@FengYeHong-HP:~$
apluser@FengYeHong-HP:~$ curl --get -w '\n' 'http://192.168.3.24:9002/curl/get'
{"name":"枫叶红","id":110120}
apluser@FengYeHong-HP:~$
apluser@FengYeHong-HP:~$ curl -X GET -w '\n' 'http://192.168.3.24:9002/curl/get'
{"name":"枫叶红","id":110120}

2.1.2-X⇔--request指定http请求方式

发送Get请求

apluser@FengYeHong-HP:~$ curl -X GET -w '\n' 'http://192.168.3.24:9002/curl/get'
{"name":"枫叶红","id":110120}

发送Post请求

apluser@FengYeHong-HP:~$ echo;curl -X POST -w '\n' \
--header 'Content-Type: application/json' \
--data-binary '{"order_id": "order134"}' \
'http://192.168.3.24:9002/curl/json/post'

{"result":"成功","type":"json请求"}

由于提交的是json数据,curl会自动推测是出post命令,-X POST可以省略

apluser@FengYeHong-HP:~$ curl -v -w '\n' \
--header 'Content-Type: application/json' \
--data-binary '{"order_id": "order134"}' \
'http://192.168.3.24:9002/curl/json/post'
*   Trying 192.168.3.24:9002...
* Connected to 192.168.3.24 (192.168.3.24) port 9002
* using HTTP/1.x
> POST /curl/json/post HTTP/1.1
> Host: 192.168.3.24:9002
> User-Agent: curl/8.15.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 24
>
* upload completely sent off: 24 bytes
< HTTP/1.1 200
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Fri, 01 Aug 2025 23:42:29 GMT
<
* Connection #0 to host 192.168.3.24 left intact
{"result":"成功","type":"json请求"}

2.2 数据提交方式相关

2.2.1-d⇔--data和--data-binary

选项全称特点
-d--data默认以 application/x-www-form-urlencoded 发送;可多次使用
--data--data等同于 -d,更长的写法
--data-binary--data-binary不会处理数据(如不转义换行等);适用于发送原始二进制,JSON,XML数据

-d / --data

--data-binary

# ⏹-d
curl -v -w '\n' \
--header 'Content-Type: application/json' \
-d '{"order_id": "order134"}' \
'http://192.168.3.24:9002/curl/json/post'

# ⏹--data
curl -v -w '\n' \
--header 'Content-Type: application/json' \
--data '{"order_id": "order134"}' \
'http://192.168.3.24:9002/curl/json/post'

# ⏹--data-binary
curl -v -w '\n' \
--header 'Content-Type: application/json' \
--data-binary '{"order_id": "order134"}' \
'http://192.168.3.24:9002/curl/json/post'

但如果省略了--header 'Content-Type: application/json'的请求头之后,使用-d / --data的话,就会默认以 application/x-www-form-urlencoded的表单方式提交数据。

curl -v -w '\n' \
--data 'order_id=order134' \
--data 'event=PLACED' \
'http://192.168.3.24:9002/curl/form/post'

2.2.2--json

2022年的7.82.0版本的curl追加了--json配置项,专门用来发送json数据。

curl -v -w '\n' \
--header 'Content-Type: application/json' \
--data-binary '{"order_id": "order134"}' \
'http://192.168.3.24:9002/curl/json/post'
curl -v -w '\n' \
--json '{"order_id": "order134"}' \
'http://192.168.3.24:9002/curl/json/post'

apluser@FengYeHong-HP:~$ echo '{"product_id": 20.5}' | \
curl -w '\n' \
--json @- \
--location 'http://192.168.3.24:9002/curl/json/post'
{"result":"成功","type":"json请求"}
apluser@FengYeHong-HP:work$ cat file.json
{"product_id": 20.5, "name": "枫叶红"}
apluser@FengYeHong-HP:work$
apluser@FengYeHong-HP:work$ curl -w '\n' \
--json @file.json \
--location 'http://192.168.3.24:9002/curl/json/post'
{"result":"成功","type":"json请求"}

2.2.3-F⇔--form

-F--form 表示使用 multipart/form-data 类型的表单提交数据

curl -v -w '\n' \
--form 'file1=@grep_cmd.txt' \
'http://192.168.3.24:9002/curl/file/upload'

上传文件的同时提交json数据

curl -v -w '\n' \
--form 'file1=@grep_cmd.txt' \
--form 'jsonData1={"name":"wangwu","age":30,"card":["abc","bbc"]}' \
--form 'jsonData1=测试信息' \
--form 'jsonData1=["名字","年龄","住址"]' \
--form 'jsonData2={"name":"zhaoliu","age":20}' \
'http://192.168.3.24:9002/curl/file/upload'

2.2.4--data和--data-urlencode和--url-query

--data--data-urlencode

curl --get -v -w '\n' \
-d 'INFILE=/data/path/out' \
--data 'JobId=CCMPLTEST01' \
--data 'OTFILE=/data/path/in' \
--data-urlencode 'name=贾 飞天' \
'http://192.168.3.24:9002/curl/get'

--url-query

curl -v -w '\n' \
--url-query 'JobId=CCMPLTEST01' \
--url-query 'OTFILE=/data/path/in' \
--url-query 'INFILE=/data/path/out' \
--url-query 'name=贾 飞天' \
'http://192.168.3.24:9002/curl/get'

2.2.5-T⇔--upload-file

curl --request PUT \
-v -w '\n' \
--header 'X-Filename: grep_cmd.txt' \
--header 'Content-Type: text/plain' \
--upload-file 'grep_cmd.txt' \
'http://192.168.3.24:9002/curl/put/file'

2.3 head相关

2.3.1-A⇔--user-agent指定用于代理字符串

curl命令,默认情况下使用User-Agent: curl/8.15.0,但是部分网站可能不允许User-Agent: curl/8.15.0的请求访问

可以通过下面3种方式指定User-Agent,模拟浏览器访问

# --user-agent 的方式
curl --get \
-v -w '\n' \
--user-agent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' \
'http://192.168.3.24:9002/curl/get'

# -A 的方式
curl -G \
-v -w '\n' \
-A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' \
'http://192.168.3.24:9002/curl/get'

# --header 的方式
curl -X GET \
-v -w '\n' \
--header 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' \
'http://192.168.3.24:9002/curl/get'

2.3.2-H⇔--header指定请求头

用于在发起请求的时候,添加请求头

curl -v -w '\n' \
--header 'X-USER-ID: jmw110' \
-H 'X-TOKEN: abc123' \
--data 'order_id=order134' \
--data 'event=PLACED' \
'http://192.168.3.24:9002/curl/form/post'

2.3.3-i和-I和-D和--show-headers

-i:在输出中包含服务器响应的 HTTP 头部信息

-I:只请求并显示响应头,不下载正文,相当于发起HEAD请求

--show-headers的作用和-i相同,语义化更好,在最新的curl版本支持

-D:将服务器返回的 HTTP 响应头(headers)输出到指定文件或标准输出

curl -sS -D - \
'https://amazon.com'

curl -sS -D - \
-o /dev/null \
'https://amazon.com'

2.4 输出相关

2.4.1-s和-S

# 显示进度条
curl --get -w '\n' \
'http://192.168.3.24:9002/curl/get' | jq .

# 不显示进度条, 但连接不上服务器报错时, 什么也不输出
curl --get -w '\n' \
-s \
'http://你好.168.3.24:9022/curl/get' | jq .

# 不显示进度条, 但连接不上服务器报错时, 显示报错信息
curl --get -w '\n' \
-sS \
'http://你好.168.3.24:9022/curl/get' | jq .

2.4.2-f⇔--fail快速失败

# 会显示出错误时的json信息
curl --get 'https://api.github.com/users/user_not_exist'
# 服务器返回404状态码时,直接报错
curl --get --fail 'https://api.github.com/users/user_not_exist'

2.4.3-v

2.4.4-w⇔--write-out

占位符含义
%{http_code}HTTP 响应状态码(如 200、404)
%{time_total}总耗时(秒),包括解析 DNS、建立连接等
%{time_namelookup}DNS 查询耗时(秒)
%{time_connect}建立连接所耗时间(秒)
%{time_starttransfer}服务器开始响应的时间(秒)
%{remote_ip}连接的远程服务器 IP
%{remote_port}远程服务器端口
%{size_download}下载的字节数
%{size_upload}上传的字节数
%{url_effective}最终的 URL(跟随跳转后的地址)
%{content_type}响应的 Content-Type 值

-w '\n':实现换行


显示 IP、端口、响应时间

curl -s -o /dev/null \
-w '\nIP: %{remote_ip}\n端口: %{remote_port}\n响应耗时: %{time_starttransfer} 秒\n' \
'https://example.com'

其他用法

apluser@FengYeHong-HP:~$ curl -sSf -o /dev/null \
-w '\nStatus: %{http_code}\nTime: %{time_total}s\n' \
'https://example.com'

Status: 200
Time: 0.538273s
# http头以外的情报输出为json
curl -sS -w '%{json}' -o /dev/null http://example.com | jq | head
# 将http头的情报输出为json的形式
curl -sS -w '%{header_json}' -o /dev/null 'https://api.github.com/users/fengyehong123' | jq | head
# 还可以这么用 %header{key的名字}
curl -sS -w '%header{content-length}\n' -o /dev/null 'https://api.github.com/users/fengyehong123'

2.4.5-o⇔--output和-O将响应内容保存到指定文件中

2.4.6-L⇔--location重定向

2.5 其他参数

2.5.1-m和--connect-timeout

2.5.2--compressed

2.5.3--variable和--expand-url

2023年11月份release的8.3.0版本的curl命令添加了变量和变量展开功能

curl -sS -w '\n' -v \
--variable 'port=9002' \
--expand-url 'http://192.168.3.24:{{port}}/curl/get/'

2.5.4--referer

简介

常见用途

curl --referer 'http://www.example.com' \
-fsS -D - -o /dev/null \
--location 'http://www.example.com'

三. 提交数据的常见格式

3.1 url传参

curl --get -v -w '\n' \
-d 'INFILE=/data/path/out' \
--data 'JobId=CCMPLTEST01' \
--data 'OTFILE=/data/path/in' \
--data-urlencode 'name=贾 飞天' \
'http://192.168.3.24:9002/curl/get'

3.2application/x-www-form-urlencoded表单提交

curl -v -w '\n' \
--data 'order_id=order134' \
--data 'event=PLACED' \
'http://192.168.3.24:9002/curl/form/post'

3.3multipart/form-data表单提交

curl -v -w '\n' \
--form 'file1=@grep_cmd.txt' \
--form 'jsonData1={"name":"wangwu","age":30,"card":["abc","bbc"]}' \
--form 'jsonData1=测试信息' \
--form 'jsonData1=["名字","年龄","住址"]' \
--form 'jsonData2={"name":"zhaoliu","age":20}' \
'http://192.168.3.24:9002/curl/file/upload'

3.4 json数据

curl -v -w '\n' \
--header 'Content-Type: application/json' \
--data-binary '{"order_id": "order134"}' \
'http://192.168.3.24:9002/curl/json/post'
curl -v -w '\n' \
--json '{"order_id": "order134"}' \
'http://192.168.3.24:9002/curl/json/post'

3.5 xml数据

curl -v -X POST \
 --location https://postman-echo.com/post \
 -H "Content-Type: application/xml; charset=UTF-8" \
 -d '<?xml version="1.0" encoding="UTF-8"?>
     <order>
      <orderId>123</orderId>
      <total>99.9</total>
     </order>'

四. 案例

直接执行网络上的脚本

curl -fsSL 'https://raw.githubusercontent.com/fengyehong123/BashStudy/refs/heads/main/99-技巧/04-随机/01-$RANDOM随机数和随机字符串.sh' | bash
bash <(curl -fsSL 'https://raw.githubusercontent.com/fengyehong123/BashStudy/refs/heads/main/99-技巧/04-随机/01-$RANDOM随机数和随机字符串.sh')

⏹下载网站上的图片

tr ' ' '\n':将空格替换为换行符,确保每一个网址一行

xargs -n 1 -P 10

--retry 3 --retry-delay 2

echo https://www.itzmx.com/{1..499}.webp | \
tr ' ' '\n' | \
xargs -n 1 -P 10 \
curl -s -O --retry 3 --retry-delay 2

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文