Linux常用命令--curl与wget

摘要

  • curl与wget的基本使用方法

  • 本文基于CentOS8(x86_64)

curl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 查看页面内容,默认GET请求
curl url

# 简单验证的页面登录方法
curl -u user:passwd url

# 下载文件要指定下载后的文件名称
curl -o fileName url
# 显示下载进度条,-C - 断点续传,-o 下载后的文件名称
curl -C - -o fileName url

# -X, --request 指定请求方法
# -d, --data DATA HTTP POST data
# -X指定请求协议,-H指定请求头,多个请求头就使用多个-H,-d指定请求数据
curl url \
-X POST \
-d "{\"data\":\"content\"}" \
-H "content-type: application/json"

curl url \
-X POST \
-d "name=zhangsan&age=30"
-H "content-type: application/x-www-form-urlencoded"

# --data-urlencode参数等同于-d,发送 POST 请求的数据体,区别在于会自动将发送的数据进行 URL 编码
curl --data-urlencode 'name=张三' url

# -G, --get Send the -d data with a HTTP GET
# 发出一个 GET 请求,实际请求的 URL 为url?name=zhangsan&age=30。如果省略-G,会发出一个 POST 请求。
curl -G -d 'name=zhangsan' -d 'age=30' url

# 上传文件,注意文件名称前面要加上@,后面跟本地文件路径,不指定type默认会把 MIME 类型设为application/octet-stream,不指定filename默认使用上传文件名称作为服务器端接收到的文件名称
curl -F 'file=@photo.png;type=image/png;filename=me.png' -H "Content-Type: multipart/form-data" url

# 同时传递文件和普通属性,有多少个参数,后面就跟多少个-F指定要上传携带的参数值
curl -F 'file=@photo.png;type=image/png;filename=me.png' -F 'name=java' -H "Content-Type: multipart/form-data" url
# 同时传递文件和json属性
curl -F 'file=@photo.png;type=image/png;filename=me.png' -F 'jsonBody={"name":"java"};type=application/json' -H "Content-Type: multipart/form-data" url

# 通过FTP进行下载,-O 将返回内容输出到当前目录下,和url中文件名相同的文件中(不含目录)
curl -O ftp://user:pass@ip:port/file 

# 通过FTP进行上传,-T 指定上传文件
curl -T file ftp://user:pass@ip:port/path 

# 自动化下载脚本常用的命令
curl -fsSL url
# 在自动化脚本中经常使用curl -fsSL,因为它具备以下几个优点:

# 1.简洁性(-s 和 -S):
# -s(--silent)使得 curl 在执行过程中不显示任何输出,包括进度信息和错误信息。这样可以清理脚本的输出,避免杂乱的信息干扰主要的脚本逻辑。
# -S(--show-error)在与-s一起使用时,即使静默模式下如果出现错误依然显示错误信息,这有助于调试和错误跟踪。
# 2.错误处理(-f):
# -f(--fail)参数确保了在 HTTP 请求失败(例如 404 或 500 错误)时,curl 不会输出错误的 HTML 内容而是直接退出并返回错误码。这使得脚本能够更容易地处理错误情况并采取相应的措施,不需要额外处理错误页面的内容。
# 3.重定向跟踪(-L):
# -L(--location)允许 curl 自动跟踪和处理 HTTP 重定向。当目标资源发生重定向时,curl 会自动请求重定向后的 URL,而不需要人工干预。这在下载内容或访问需要重定向的资源时非常有用。
# 4.简化下载操作:
# 通过组合这些参数,curl -fsSL可以在一个简洁的命令中完成下载文件等操作,处理常见的错误情况,并简化自动化脚本的编写和维护。

# 这些特性使得curl -fsSL成为自动化脚本中下载文件、处理 HTTP 请求的一个常用且高效的选择

解决 curl: (60) SSL certificate problem: certificate has expired 的问题

  • 发生问题的原因:

    • 请求的网站的证书过期,需要更新网站证书

    此时若不能更新网站证书,可以使用下面的命令忽略证书验证

    1
    2
    3
    4
    5
    6
    7
    # 通过忽略证书验证的方式解决
    curl --insecure https://www.example.com
    # 忽略证书校验,但是显示警告
    curl --insecure --verbose https://www.example.com
    # 或者
    curl -k https://www.example.com
    curl -k -v https://www.example.com
    • 系统的根证书过期,需要更新系统根证书

    手动下载最新的根证书进行更新

    1
    2
    3
    4
    5
    6
    # 显示libcurl使用的CA证书捆绑包的内置路径,用于解决 curl: (60) SSL certificate problem: certificate has expired 的问题时,定位证书的位置,然后从  https://curl.se/docs/caextract.html 下载新版进行替换
    curl-config --ca
    # 如果 curl-config 命令不存在,可以通过如下命令进行安装
    yum install curl-devel
    # 验证是否安装成功
    curl-config --version

    命令行更新根证书(推荐)

    1
    yum update -y ca-certificates
  • 实战示例

在 curl 命令执行失败或者返回状态码不为 200 时打印信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

# 执行 curl 命令
curl_output=$(curl --retry 3 -m 10 -I -s -o /dev/null -w "%{http_code}" http://localhost:8080/test.html)

# 获取 curl 命令的退出状态码
exit_status=$?

# 检查命令的退出状态码和返回的状态码
if [ $exit_status -ne 0 ] || [ $curl_output -ne 200 ]; then
# 打印格式化后的系统时间
current_time=$(date +"%Y-%m-%d %H:%M:%S")
echo "curl 命令执行失败,或者返回的状态码不为 200,当前系统时间为:$current_time"
fi

参数解释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
--retry 3:重试 3 次。

-m 10:设置单个请求的最大请求时间为 10 秒。如果服务器在 10 秒内没有响应,curl 将中断请求。

-I:仅请求头。-I 参数告诉 curl 发送 HEAD 请求而不是默认的 GET 请求,这样服务器将只返回 HTTP 头信息而不返回实际内容。

-s:静默模式。-s 参数告诉 curl 在执行时不显示进度条或错误信息,只输出请求的结果。

-o /dev/null:将输出重定向到 /dev/null,这个设备是一个特殊的文件,会将所有写入的数据都丢弃。由于我们只关心 HTTP 状态码,而不关心输出内容,因此将其重定向到 /dev/null 是合理的。

-w "%{http_code}":自定义输出格式。-w 参数允许您指定 curl 命令输出的格式。在这里,%{http_code} 表示将输出 HTTP 响应的状态码。
您还可以指定其他内容,例如:
%{time_total}:总请求时间,包括 DNS 解析、连接、传输和重定向时间。
%{time_namelookup}:DNS 解析时间。
%{time_connect}:建立连接时间。
%{time_starttransfer}:服务器开始响应时间。
%{size_download}:下载的数据大小。
%{size_upload}:上传的数据大小。
%{url_effective}:最终请求的 URL。
%{content_type}:返回的内容类型。
%{remote_ip}:远程服务器 IP 地址等。

小贴士

  • 有些系统没有默认安装curl,可以通过yum install curl -y的方式进行安装,也可以通过源码进行安装,这里给出源码安装的过程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 安装依赖
yum install gcc cmake openssl openssl-devel

# 下载源码:https://github.com/curl/curl/releases/
wget https://github.com/curl/curl/releases/download/curl-8_0_1/curl-8.0.1.tar.gz
tar -zxcf curl-8.0.1.tar.gz

# 进入curl目录下,创建一个build文件夹,用于存放编译产生的中间文件、动态库、头文件等内容
cd curl-8.0.1
mkdir build
cd build

# 通过cmke生成Makefile,注意,cmake的语法是:cmake [路径],.. 表示上一级目录
cmake ..

# 编译并安装
make && make install

# 更新系统的链接库
ldconfig -v

wget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 下载到当前目录
wget url
# 下载到指定文件中
wget -O saveFile url
# 下载file.txt中的所有链接
wget -i file.txt
# 断点续传,最多重试5次
wget -c -t 5 url
# 递归下载整个网站,递归深度为5
wget -r -l 5 url
# 不下载已经存在的文件,设置超时时间5s
wget -nc -T 5 url
# 下载速度限制为1m/s,默认全速下载
wget --limit-rate=1m url
# 使用需要用户名和密码认证的ftp下载
wget --ftp-user=USERNAME --ftp-password=PASSWORD ftp://url
# 访问https连接提示证书过期时,如果确认可以安全访问,可以加上--no-check-certificate
wget --no-check-certificate https://xxxxx

小贴士

一般情况下我们都是在比较简单的GET请求下使用wget,实际上wget也支持一些复杂的场景

  • POST请求
1
2
# 'key1=value1&key2=value2'这部分会被作为POST请求的数据体
wget --post-data 'key1=value1&key2=value2' http://example.com/resource
  • 携带Header

1
wget --header="Accept-Encoding: gzip" --header="User-Agent: My-App-Name/0.0.1" http://example.com
  • 携带Cookie

1
2
3
4
5
6
7
wget --header="Cookie: name=value" http://example.com
# 如果你有多个Cookie需要设置,可以分别为它们添加--header选项
wget --header="Cookie: name1=value1" --header="Cookie: name2=value2" http://example.com
# 你也可以将所有的cookie放在一个文件中,然后使用--load-cookies选项来读取
wget --load-cookies cookies.txt http://example.com
# 这里cookies.txt文件应该是 Netscape/Mozilla cookie file 格式,可以由 Chrome 浏览器插件 (Get cookies.txt LOCALLY
0) 自动导出。
  • 克隆整个网站

1
2
3
4
5
6
7
8
9
10
11
12
13
14
wget --mirror --convert-links --adjust-extension --page-requisites --no-parent http://example.com

# 这个 wget 命令用来创建一个网站的镜像,即抓取整个网站的内容。下面我们逐一解释这些参数的含义:
# --mirror:这个选项让 wget 具有镜像(即抓取整个网站)的功能,它等同于 -r -N -l inf --no-remove-listing,即递归下载、只下载新的文件、无限制递归深度,保持服务器上的文件列表。
# --convert-links:下载完成后,将文档中的链接转换为本地链接。例如,如果初始文档中链接为 /dir/foo.html,在下载后,这个链接会被替换为 file:/dir/foo.html,这样你就可以在离线浏览时能正常访问其他页面。
# --adjust-extension : 如果文件(服务器上)没有扩展名,这个参数可以添加合适的扩展名(比如,服务器那边是 text/html 的内容,但 URL 中没有 .html 结尾,这个参数则会添加 .html 扩展名)。
# --page-requisites:这个选项使 wget 下载所有页面需要的元素,比如图片、CSS样式等,即使这些内容没有在同一台服务器上。这样就能确保在离线的情况下,网页依然能完全显示。
# --no-parent:这个选项限制了目录的链接到父目录之外的链接,反正换句话说,wget 只会下载子目录,而不会返回到父目录。这对镜像站点来说是有用的。
# 总的来看,这个命令将会创建一个完整的网站复制,包括所有链接,图片和文件,并且可以在本地完全离线查看。

# 只下载rar格式的文件
wget -m --accept=rar url
# 不下载gif格式的文件
wget -m --reject=gif url