你是否下載過一個非常巨大的文件,以至于你不得不將你的web瀏覽器幾個小時甚至幾天的打開?假如你有一個40個文件鏈接在一個web頁上,你又需要它——你愿意不厭期煩的一個一個的點開它們嗎?再假如瀏覽器在工作完成前發生了故障呢?Linux 早已擁有一系列用手動的工具來對付這種情況,它完全不用使用瀏覽器。支持斷點續傳、鏡像下載、計劃下載等windows下載工具的所有功能:)??岵豢??下面,就跟我來吧!
在這種方式中存在的交互性
Web瀏覽器是使Web具有交互性——點擊然后希望結果能在幾秒鐘內出來。但是,即使是在很快的線路里,下載許多文件仍然需要相當長的時間。例如ISO鏡像文件就被普遍用在GNU/Linux的CD-ROM發行版中。一些web瀏覽器,尤其是只有簡單編碼的瀏覽器,對于長時間的工作并不能很好的運作,它可能會漏掉記憶存儲或者會不合時宜的發生故障。盡管將一些瀏覽器和文件管理器已經結合起來了,但仍然不能支持多個文件的下載及捆綁傳送(就是將幾個文件捆綁在一起以便于傳送)。所以你不得不保持登錄狀態直到整個文件下載完畢。最后你還得去你的辦公室點擊鏈接開始下載,而這樣你會因為共享了同事的帶寬而使他很不高興。
下載大型文件這個任務更適合另外一套工具來完成。這篇文章將告訴你怎么樣把各種GNU/Linux 的應用程序結合起來,也就是lynx,wget,at,crontab等等來解決各種文件傳送中的問題。我們將用到一些簡單的腳本,所以有一點bash shell方面的知識對下面的學習會有幫助。
wget 應用程序
其主要分類包括wget 下載工具。
bash$ wget
它還可以處理FTP、時間戳及遞歸的鏡像整個web網站的目錄樹——如果你一不小心,整個web網站及所有別的站點就會鏈接到:
bash$ wget -m
由于潛在的高負載,這個工具被放在服務器中,這個工具在下載過程中會自動根據“robots.txt”中的鏡像優化下載。這里有幾個命令選項以控制那些被下載,并限制跟隨的鏈接的類型和下載文件的類型。例如:僅跟隨相對鏈接并跳過GIF:
bash$ wget -m -L --reject=gif
當然它支持斷點續傳。當將不完整的文件給予它以拼接剩余的數據時, wget能恢復被打斷的下載(“-c”選項)。這個操作需要服務器的支持。
bash$ wget -c
斷點續傳可以和鏡像功能結合起來,可以使一個很大的文件通過不同的會話中下載然后再拼接起來。如何使這個過程自動完成將在稍后介紹。
如果你常常像我一樣經常下載的時候被中斷,你可以讓wget多重試幾次:
bash$ wget -t 5
這里是說試驗5次后放棄,你也可以使用“-t inf”表示不放棄直到得到結果。
那么如何使用防火墻代理下載呢?使用http_proxy環境變量或者是 .wgetrc配置文件指定一個代理服務器,通過它下載。如果使用斷點續傳通過代理服務器下載的話,是會失敗的。因為代理一個斷點續傳的話,代理服務器僅能存儲一個文件的不完全的拷貝。當你試圖使用"wget -c"以獲得文件的剩余部分時,代理服務器會核對存儲文件,并會給出錯誤的信息告之你已經有了整個文件。為了成功的繞過文件的存儲過程,我們通過在下載請求中加上一個特殊的頭信息騙過代理服務器:
bash$ wget -c --header="Pragma: no-cache"
“--header”選項可以加入任何頭信息的數字或者約定的字符串,這樣我們就可以修改web服務器和代理器的性能。一些站點拒絕對通過外面來源鏈接的文件提供服務,只有來源于經過它同意的站點的其他頁面時,文件內容才可以傳送到瀏覽器當中。你可以通過添加一個“Referer:”頭信息來傳送文件:
bash$ wget --header="Referer: "
一些特殊的非公眾的web站點只能將內容發送到一些特別的類型的瀏覽器中??梢允褂谩癠ser-Agent:”頭信息發送:
bash$ wget --header="User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"
(注意:以上提供的技巧是被使用在滿足內容許可機制的情況下使用。否則,將是違法的行為。)
指定下載的時間
如果你想在你辦公室的與你的同事共用一根線路的電腦里下載大型文件,想象一下他們因為原本像暢快的小溪一樣的線路突然便得像爬蟲一樣慢而發怒的樣子,你就會考慮將你的文件傳送時候改在非高峰使用期了。你不必在等到每個人都離開后還呆在辦公室里,也不必在飯后在家中遠程登錄。你只要在工作日程安排程序中做以下設置:
bash$ at 2300
warning: commands will be executed using /bin/sh
at> wget
at> press Ctrl-D
我們設定在晚上23點的時候開始下載。我們要做的就是確信atd這個日程安排守護進程還在工作^&^。
下載要花好幾天?
當你下載的一個或多個文件包含許多數據,而機器的帶寬使得它的傳送速度可以和信鴿相比的時候,你會發現當你在第二天早上到了公司,預定的下載還沒有完成。你終止這個工作而且提交另外一個at工作,這次你使用了“wget -c”,只要下載沒有完成,就每天都重復這個工作。這時候最好是使用“crontab.txt”自動執行它。建立一個名為 “crontab.txt”的純文本文件,內容如下:
0 23 * * 1-5 wget -c -N
0 6 * * 1-5 killall wget
這將是crontab文件,它指定周期性的執行什么工作。前面的五欄指定什么時候開始執行命令,每行的后面部分指定執行什么。前兩欄指定時間——晚上23點整開始wget,早晨6點整就killall wget。位于第三第四的* 表示每個月的每一天都可以進行這樣的工作。第五欄表示每個星期的哪些天安排了工作時間進程——“1-5”表示星期一到星期五。
每個工作日的晚上23點下載工作開始,早6點整下載工作停止。為使這個crontab工作時間表發揮作用,你需要鍵入以下命令:
bash$ crontab crontab.txt
“-N”參數將檢查目標文件的時間郵戳,當它找到了匹配的時間戳,它就會終止下載,因為它表明整個這個文件已經被傳送?!癱rontab -r”可以取消這個日程時間安排。我使用這種方法來通過撥號上網下載了許多ISO文件。
下載動態網頁
一些動態的網頁需根據需要產生,常常頻繁的變動。既然目標文件從技術角度上講不能算是一個文件,那么也就無所謂什么文件長度,繼續下載也就變得毫無意義——“-c” 選項難以工作。例如:在Linux Weekend News中生成PHP頁:
bash$ wget
假如你中斷了下載,然后又想繼續,它將從頭開始下載。我辦公室的Net線路有時候慢得讓人受不了,所以我寫了一個簡單的腳本用來決定什么時候中斷傳遞動態的HTML頁:
#!/bin/bash
#create it if absent
touch bigpage.php3
#check if we got the whole thing
while ! grep -qi @#</html>@# bigpage.php3
do
rm -f bigpage.php3
#download LWN in one big page
wget
done
這個bash腳本在找到“</html>”之前會一直下載文檔,“</html>”標志著文件的結束。
SSL和Cookies
用“https://”開頭可以通過SSL(Secure Sockets Layer,安全套接口層)訪問遠程文件。你會發現另外一個名為curl的下載軟件, 在有些情況下使用它會相當便利。
一些web站點在提供你想要的服務內容之前會給瀏覽器強行灌輸許多cookie。加上一個“Cookie:”頭和正確的信息,這個信息可以從你的瀏覽器的cookie文件中獲得。
bash$ cookie=$( grep nytimes ~/.lynx_cookies |awk @#{printf("%s=%s;",$6,$7)}@# )
為了從下載資料,上面的腳本可以構建你所需要的cookies。當然前提是你已經為使用這個瀏覽器的站點注冊了。w3m使用了一個稍微有點不同的cookie文件格式:
bash$ cookie=$( grep nytimes ~/.w3m/cookie |awk @#{printf("%s=%s;",$2,$3)}@# )
可以用下面這個bash執行下載:
bash$ wget --header="Cookie: $cookie"
也可以使用curl工具:
bash$ curl -v -b $cookie -o supercomp.html
URLs列表
目前為止,我們下載的文件都是單個的文件或者鏡像整個站點,也是存儲整個網站目錄。但有時候我們想下載幾個文件,當然,它的URL已經在web頁中給出,而又不想將整個站點都存儲下來。一個簡單的例子就是,我們只想將站點中排列好了的100個音樂文件的前面20個下載回來。在這里“--aclearcase/" target="_blank" >ccept”和“--reject”因為不是在文件擴展部分都不可以使用。所以,我們使用“lynx -dump”。
bash$ lynx -dump |grep @#gz$@# |tail -10 |awk @#{print $2}@# > urllist.txt
使用很多GNU文本處理工具都可以把來自lynx的輸出過濾一下。在上面這個例子里,我們將在“gz”中的URL的結尾析取出來并將最后10個文件存儲下來。一個很小的bash腳本命令可以自動下載文件中列出的所有URLs:
bash$ for x in $(cat urllist.txt)
> do
> wget $x
> done
我們已經成功的將Linux Gazette的最近十期下載下來。
如何處理帶寬問題
如果你對帶寬不是很熟,而且你的文件下載因為你在web服務器的終端而非常慢的時候,下面這個技巧可以幫助你暢通無阻的傳送文件。它需要使用到curl和幾個鏡像web站點,在那里有目標文件的幾個相同的備份。例如,假設你想從下面三個站點下載Mandrake 8.0的ISO :
url1=http://ftp.eecs.umich.edu/pub/linux/mandrake/iso/Mandrake80-inst.iso
url2=http://ftp.rpmfind.net/linux/Mandrake/iso/Mandrake80-inst.iso
url3=http://ftp.wayne.edu/linux/mandrake/iso/Mandrake80-inst.iso
文件長度是677281792,使用curl的“--range” 選項同時分三部分下載。
bash$ curl -r 0-199999999 -o mdk-iso.part1 $url1 &
bash$ curl -r 200000000-399999999 -o mdk-iso.part2 $url2 &
bash$ curl -r 400000000- -o mdk-iso.part3 $url3 &
分成了三個下載過程,不同的服務器傳送ISO鏡像文件的不同部分?!?r”選項指定從目標文件中選取的字節范圍。完成后,再將三個部分合在一起——cat mdk-iso.part? > mdk-80.iso。(在燒錄到CD-R之前建議你檢查md5散列)curl使用“--verbose”選項并在它自己的窗口中運行的話可以追蹤每個傳送過程。
總結
不要害怕使用非交互性方式來下載遠程文件。web設計者設法強迫我們在他們的站點上交互式的沖浪,但仍然有免費的工具幫助我們自動進行這個工作,省下我們不少麻煩哦。