Linux

Linux 網路資料傳輸 curl 指令教學與範例

介紹如何在 Linux 系統中使用 curl 指令進行各種網路資料的下載與上傳。

安裝 curl 工具

若在 Ubuntu 或 Debian 系列的 Linux 中,可以使用 apt 安裝 curl 套件:

# 安裝 curl 套件(Ubuntu/Debian)
sudo apt install curl

若在 Red Hat 系列的 Linux 中,則可透過 yum 安裝 curl 套件:

# 安裝 curl 套件(RHEL/Fedora/CentOS)
sudo yum install curl

下載網頁

直接執行 curl 指令,並指定網址,即可下載網頁的內容:

# 取得 Google 首頁網頁內容
curl https://www.google.com.tw/

若網頁伺服器不是開在標準的 80 連接埠,亦可另外在網址中指定連接埠,例如:

# 取得指定網頁伺服器 8080 連接埠的網頁內容
curl http://www.example.com:8080/

下載檔案

curl 預設會直接輸出下載的網頁 HTML 原始碼貨檔案內容,若要將下載的內容儲存至檔案中,可以加上 -o 參數來指定儲存的檔案名稱:

# 將下載內容儲存至 jquery.min.js
curl -o jquery.min.js https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js

若要直接以原始的名稱作為儲存的檔案名稱,可以改用 -O 參數,這樣就不必再另外指定檔案名稱:

# 將下載內容儲存至 jquery.min.js
curl -O https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js

也可以一次下載多個檔案:

# 下載多個檔案
curl -O https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js \
     -O https://cdn.jsdelivr.net/npm/jquery-ui/ui/widget.min.js

檔案續傳

如果在使用 curl 下載大型檔案的過程中,因為網路問題造成下載中斷,再次下載時,可以加上 -C - 參數,以續傳功能從上次斷掉的地方繼續下載。

假設我們使用了以下指令下載一個大型的 ISO 檔案:

# 下載大型檔案
curl -O http://releases.ubuntu.com/21.04/ubuntu-21.04-desktop-amd64.iso

如果在下載過程中斷了,可以執行以下指令以續傳的方式繼續下載:

# 以續傳功能繼續下載
curl -C - -O http://releases.ubuntu.com/21.04/ubuntu-21.04-desktop-amd64.iso

傳送 HTTP 的 POST 請求

若要使用 curl 送出 HTTP 的 POST 請求,可以使用 -d 參數來指定資料內容,其格式如下:

變數1=內容1&變數2=內容2&變數3=內容3&...

其中所有的內容都必須經過百分號編碼

假設在網頁上有一個採用 POST 的表單:

<!-- POST 網頁表單 -->
<form action="post.cgi" method="post">
  <input name="user" />
  <input name="pass" type="password" />
  <input name="id" type="hidden" value="ABC123" />
  <input name="ding" value="submit" />
</form>

若想要用 curl 模擬送出這個 POST 請求,可以這樣寫:

# 送出 POST 請求
curl -d "user=foobar&pass=12345&id=ABC123&ding=submit" \
  https://www.example.com/post.cgi

上傳檔案

若要以 curl 上傳檔案,可以使用 -F 參數指定上傳的檔案,指定檔案的方式如下:

名稱=@檔案名稱

例如透過 profile 表單欄位,上傳 portrait.jpg 圖片檔案至網頁伺服器:

# 上傳檔案
curl -F "profile=@portrait.jpg" https://example.com/upload.cgi

亦可在檔案名稱後方加上分號之後,加入上傳檔案的類型資訊:

# 指定檔案類型
curl -F "web=@index.html;type=text/html" https://example.com/upload.cgi

下載 FTP 檔案

curl 亦可用來下載 FTP 伺服器上面的檔案,若直接指定 FTP 的目錄,會列出該目錄中的檔案清單:

# 取得 FTP 伺服器指定目錄的檔案清單
curl ftp://ftp.gnu.org/

若指定 FTP 的檔案,則可直輸出該檔案內容:

# 取得 FTP 伺服器上的 README 檔案內容
curl ftp://ftp.gnu.org/README

若要將下載的內容儲存為檔案,一樣可以使用 -o-O 參數:

# 將下載內容儲存至 README
curl -o README ftp://ftp.gnu.org/README

# 將下載內容儲存至 README
curl -O ftp://ftp.gnu.org/README

若 FTP 需要帳號與密碼登入,可以使用 -u--user 參數來指定帳號與密碼:

# 以帳號密碼登入 FTP 伺服器
curl -u FTP_USERNAME:FTP_PASSWORD ftp://ftp.example.com/

其中 FTP_USERNAME 就是 FTP 的帳號,而 FTP_PASSWORD 則為密碼。

上傳 FTP 檔案

若要上傳檔案至 FTP 伺服器,可以使用 -T--upload-file 參數:

# 上傳 newfile.gz 至 FTP 伺服器
curl -T newfile.gz -u FTP_USERNAME:FTP_PASSWORD ftp://ftp.example.com/

HTTP 標頭資訊

HTTP 的標頭資訊對於開發與除錯非常有用,若要查看 HTTP 標頭資訊,可以在執行 curl 指令時加上 -I 參數:

# 顯示 HTTP 標頭資訊
curl -I https://www.google.com.tw/
HTTP/2 200
content-type: text/html; charset=Big5
p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
date: Mon, 04 Oct 2021 01:32:13 GMT
server: gws
x-xss-protection: 0
x-frame-options: SAMEORIGIN
expires: Mon, 04 Oct 2021 01:32:13 GMT
cache-control: private
set-cookie: 1P_JAR=2021-10-04-01; expires=Wed, 03-Nov-2021 01:32:13 GMT; path=/; domain=.google.com.tw; Secure
set-cookie: NID=511=FdThXNf13hqj_sLenQMm3g435gKt3Mb-2LkGhl7s-dzVetVsXaTZLLtn2TyATO1j1SYqqz2ds298MALpEClBmm1OS9AW3OnJG9KfpDEGgV5I3-toONoZuALPqmh5wV5TlwZFE2gTRF_q-C0kYTx0TE9reShW2nWZ3Mg9_QPrrPs; expires=Tue, 05-Apr-2022 01:32:13 GMT; path=/; domain=.google.com.tw; HttpOnly
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"

自動重新導向

curl 預設不會自動根據 HTTP Location 標頭資訊重新導向,例如

# 取得伺服器回應內容
curl https://google.com/
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>

若希望 curl 自動重新導向新的網址,可以加上 -L 參數:

# 自動重新導向
curl -L https://google.com/

指定 User-Agent

有時候網頁伺服器會阻擋 curl 的下載請求,這時候就可以透過修改 User-Agent 標頭,模擬正常使用者送出的請求。

若要指定 User-Agent 屬性,可以使用 -A 參數,例如模擬 Google Chrome 94:

# 設定 User-Agent 標頭屬性
curl -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36" https://www.google.com.tw/

限制傳輸速度

若要限制 curl 的資料傳輸速度,可以使用 --limit-rate 參數來指定資料傳輸速度的上限:

# 限制資料傳輸速度為 1MB/s
curl --limit-rate 1M -O http://releases.ubuntu.com/21.04/ubuntu-21.04-desktop-amd64.iso

這裡使用 --limit-rate 參數所指定的傳輸速度上限值,可用的單位有 KB(Kk)、MB(Mm)、GB(Gg),例如 200k3M1G 等。

設定 Cookies

在開發或是除錯時,常會需要在 HTTP 標頭中設定 cookies 以進行使用者認證等程序。

若要讓 curl 送出的請求可以附帶 cookies,可以使用 -b 參數設定 cookies 的內容:

# 設定 Cookies
curl -L -b "sid=abcd1234" -O https://my.example.com/private/

使用代理伺服器

若要讓 curl 使用代理伺服器(proxy),可以用 -x 參數指定代理伺服器位址:

# 使用代理伺服器
curl -x 192.168.5.1:8888 https://www.google.com.tw/

如果代理伺服器需要帳號與密碼,可以使用 -U--proxy-user 參數來指定:

# 指定代理伺服器帳號、密碼
curl -U username:password -x 192.168.5.1:8888 https://www.google.com.tw/

實際應用

測試伺服器是否支援 HTTP/2 協定

若要測試指定的網頁伺服器是否支援 HTTP/2 協定,可以執行:

# 目標網頁伺服器
URL="https://www.google.com.tw/"

# 嘗試以 HTTP 2.0 送出請求
HTTP_VERSION=$(curl -I --http2 -s ${URL} | grep HTTP | cut -d' ' -f1)

# 判斷 HTTP 版本
if [[ $HTTP_VERSION == "HTTP/2" ]]
then
  echo "HTTP 2.0"
elif [[ $HTTP_VERSION == "HTTP/1.1" ]]
then
  echo "HTTP 1.1"
fi

參考資料

Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago