Linux下cURL使用教程之十:HTTP文件下载

其实每次我们使用curl去打开一个url都是执行一次下载操作,因此我们甚至可以认为curl是一个下载工具。
而且curl的某些选项及特性,使得curl能完成非常强大的下载功能。
基本命令及一些有用的参数如下。

基本命令

使用curl [URL...]下载URL,并输出在终端。
可指定多个URL。多个URL时,下载内容同时在终端显示。

-#/–progress-bar 进度条

添加参数-#/--progress-bar查看下载进度条。

-o/–output 输出文件

使用参数-o/--output <file>下载并保存至文件file。
可同时下载多个URL,每个-o对应一个URL。
如:

curl -o a.html http://www.a.com http://www.b.com

会下载www.a.com的内容在a.html中,并在终端输出www.b.com的内容。而

curl -o a.html http://www.a.com -o b.html http://www.b.com

或者

curl -o a.html -o b.html http://www.a.com http://www.b.com

会分别下载两个URL至两个文件中。

-O/–remote-name

下载并从url中提取文件名。
多个URL的情况同-o选项相同:

curl -O -O http://www.xxx.com/a.html http://www.xxx.com/b.html
curl -O http://www.xxx.com/a.html -O http://www.xxx.com/b.html

都会将两个URL分别保存在a.html和b.html中。

-C/–continue-at 断点续传

使用参数-C/--continue-at <offset>进行断点续传。offset参数指定跳过多少bytes。
“-C -”指定自动检测断点续传开始位置。
使用

curl -# -O http://dl_dir.qq.com/qqfile/qd/QQ2012Beta3_QQProtect2.8.exe

下载QQ安装程序,在下载未完成时Ctrl+C结束下载,然后使用

curl -# -C - -O http://dl_dir.qq.com/qqfile/qd/QQ2012Beta3_QQProtect2.8.exe

进行断点续传。可看到第二次下载时并不是重新下载,而是从上次结束的地方下载。

-r/–range 分块下载

使用-r/--range <range>分块下载,指定每块下载的字节范围。如上例中下载qq,分块下载如下:

curl -r 0-10240 -o qq.exe.part1 http://dl_dir.qq.com/qqfile/qd/QQ2012Beta3_QQProtect2.8.exe

下载前10240bytes。

curl -r 10241-20480 -o qq.exe.part2 http://dl_dir.qq.com/qqfile/qd/QQ2012Beta3_QQProtect2.8.exe

下载10241-20480bytes。

curl -r 20481- -o qq.exe.part3 http://dl_dir.qq.com/qqfile/qd/QQ2012Beta3_QQProtect2.8.exe

下载20481bytes及之后的字节。
下载完后可使用cat qq.exe.part>qq.exe的形式得到完整文件(win下需要使用copy /b)。
此选项适用于HTTP/FTP/SFTP及本地文件。

–limit-rate 限速下载

使用参数--limit-rate <speed>限速下载。默认单位为bytes/s,’k’或’K’指定使用单位KB/s,可以使用’m’或’M’指定使用单位MB/s,’g’或’G’指定使用单位GB/s。如

curl -# -O --limit-rate 100K http://dl_dir.qq.com/qqfile/qd/QQ2012Beta3_QQProtect2.8.exe

指定限速为100KB/s。
限速是限制平均速度,某时刻的突发速度可能超过限制速度,但平均速度会低于限制速度。
如果同时使用了-Y/–speed-limit限制了最低下载速度,-Y/–speed-limit选择优先级更高。因此如果-Y/–speed-limit指定的值高于限制的速度,那么限制的速度回被突破,以保证最低下载速度有效(因为如果低于-Y/–speed-limit指定的最低下载速度,下载会被取消)。

-y/-Y 限制速度

使用参数-y/--speed-time <time>-Y/--speed-limit <speed>限制速度。
网速太慢时取消下载。

  • -Y指定最低速度。使用-y指定超时时间而未指定最低速度时,最低速度默认为1.
  • -y指定超时时间,即低于最低速度多次时间时取消下载。使用-Y指定最低速度而未指定超时时间时,超时时间默认为30。

-z/–time-cond 更新下载

使用参数-z/--time-cond <date expression>设置只在更新时下载。具体的时间格式请参考man 3 curl_getdate(这个只有在安装了libcurl开发库之后才有),或者curl_getdate在线文档
如果时间格式解析失败,curl将会把此字段理解为文件名,从文件中读取时间。
需要网页中有相关字段表明最后更新日期。
如curl_getdate在线文档网页内有字段:

Page updated June 20, 2012.

表明网页最后更新日期是2012-06-20,因此执行

curl -z 20-jun-12 http://curl.haxx.se/libcurl/c/curl_getdate.html

curl_getdate.html在2012-06-20以后被更新,会被下载。而在日期前加上”-“,则表示相反意思,如:

curl -z -20-jun-12 http://curl.haxx.se/libcurl/c/curl_getdate.html

只有 curl_getdate.html 在2012-06-20之前被更新才会下载。因此此命令不会下载curl_getdate.html。

文件批量下载

通过使用正则表达式,可以对有一定规律的文件批量下载。如我们在PHP服务器的/var/www下新建a、b两个目录,新建如下文件:
a/1.php a/2.php...a/7.php,b/1.php b/2.php...b/5.php
PHP文件内容相同,都为输出绝对路径,用以标志文件的不同:

<?php
echo __FILE__ ;
?>

可以使用命令:

curl -O http://127.0.0.1/{a,b}/[1-7].php

批量下载文件。
a/1.php-a/7.php会保存在当前目录下的1.php-7.php中。b/1.php-b/5.php如果也保存在当前目录下的1.php-5.php的话,会覆盖以前的文件。因此curl会把b/1.php-b/5.php的内容在终端输出而不会保存文件。而执行:

curl "http://10.1.1.103/{a,b}/[1-7].php" -o "#1_#2.php"

则会使用“目录文件”的形式命名文件,避免文件名冲突。
{}、[]类似于正则表达式中的语法,用以取得多个文件。#加数字的形式用以取得正则表达式的当前值。
如#1表示第一个正则表达式的当前值,上例中即为{a,b}的值。
当下载http://10.1.1.103/a/1.php时,#1为“a”,#2为“1”,#1
#2.php即为“a_1.php”。从而完成批量文件的自动命名。

注:注意此时网址包含在双引号中,这是因为如果不被包含在引号中,{}中的内容无法使用#1的形式引用,会出现如下错误

internal error: invalid pattern type (0)
Warning: bad output glob!

总结

其实日常使用,我们更多使用wget下载文件。相比wget,curl功能更具体一些。
关于二者的区别,请参考后续文章。