Bat腳本處理ftp超強案例解說

轉自 http://369369.blog.51cto.com/319630/842341

前言:

   公司有幾百臺windows服務器,每次程序更新,如果是一臺臺拷數據,只怕安排十個人,一天都不一定做得完,所以就必須研究個全自動更新方案來,於是就想到了FTP,做個主FTP站,在幾百臺客戶機上啓動BAT腳本,每30秒檢測一次,如果主站有更新程序,就自動下載更新,幾分鐘內,上400臺windows服務器,都可以全自動更新程序完畢,相當實用,現把當初研究BAT的腳本思路貼出來,希望對大批量運維人員一個方向。當然,批量更新服務器,每個公司有它自己的解決辦法,這個BAT的方式不是最優的,可以用shell,可以用perl,也可以用python等腳本解決。

一、FTP命令說明

1、在windows系統中因爲FTP是一個程序,如果在bat腳本中直接調用FTP的命令,在執行時總會彈出命令行窗口,循環在>FTP光標這,所以要換種方式,利用-S:filename,更多的命令請輸入-h查看。

2、FTP登錄成功後,需要下載遠程單個文件時,使用get命令,如果下載多個文件時,用mget,它支持通配符,在使用mget時,需要對每一個文件都進行選擇Y/N,如果想不交互的下載全部的文件,可以輸入一次prompt命令關閉交互方式。
Mput和mget命令要注意兩個問題:
Ⅰ、不能對目標文件指定命字,在命令行上所有的文件都視做源文件
Ⅱ、mput,mget兩個命令不能對目錄進行上傳與下載,只能對文件
Ⅲ、Prompt:每次執行一個這個命令,就在on ,off之間循環,ftp腳本開始時,prompt默認爲on,所以一般在上傳、下載文件時,執行一次prompt,把交互式的on關掉,變爲off。

3、文件的傳輸方式:
Binary ,二進制傳輸
Ascii ,ascII傳輸
   在FTP文件傳輸過程中,ASCII傳輸HTML和文本編寫的文件,而二進制碼傳輸可以傳送文本和非文本(執行文件,壓縮文件,圖片等),具有通用性,二進制碼傳輸速度比ASCII傳輸要快,所以在建立bat腳本時,一般輸入bin命令,啓用二進制傳輸。如果用ASCII模式傳輸非文本文件,可能會顯示一堆亂碼,如果是上傳一些CGI腳本,有可能將無法運行這類腳本,而在瀏覽器上看到server 500 error的錯誤。
Ascii和binary模式的區別是回車換行的處理。binary模式不對數據進行任何處理,asci模式將回車換行轉換爲本機的回車字符,比如Unix下是\n,Windows下是\r\n,Mac下是\r。unix系統下行結束符是一個字節,即十六進制的0A,而ms的系統是兩個字節,即十六進制的0D0A。
    所以當你用ascii方式從unix的ftp server下載文件時(不管是二進制或者文本文件,redhat的 vsftp默認是binary,ascii默認關閉),每檢測到一個字節是0A,就會自動插入一個0D,所以如果你的文件是二進制文件比如可執行文件、壓縮包什麼的,就肯定不能用了。如果你的文件就是unix下的文本文件,你用 ascii模式是正確的,要是誤用了binary模式,你在windows上看這個文件是沒有換行的,裏面是一個個的黑方塊。
   在用FTP客戶端傳輸文件時,因爲這些軟件都做得比較智能化,它可以根據後綴,自動啓用傳輸模式,所以不用擔心出問題。

二、實例求證:
    環境說明:192.168.133.34上有一FTP服務器端(windows版),FTP用戶名爲lgh,密碼爲www.liuguohua.com。該用戶的根目錄爲D:\lgh。裏面文件見下圖。sql.rar是sql.bat的壓縮文件,大家注意看圖,我等下會在後面的實例中引用這個文件,把mget,get,prompt,bin,ascii等ftp命令詮釋得一清二白。

 

實例一:直接BAT調用FTP命令
ftp.bat內容
(***大家建立bat文件不要命名爲ftp.bat,執行時會有問題***)
 

  1. ftp 
  2. open 192.168.133.34 
  3. lgh 
  4. www.liuguohua.com 
  5. get sql.rar 
  6. bye 

    從圖上的結果看,bat腳本直接調用xp的FTP命令是不行的,執行時H:\>ftp會一直死循環。我這裏的XP系統是SP3的,其它版本的,我沒有作測試。如果有不同,歡迎大家留言告之。

實例二:用put,get上傳,下載單個文件

把XP機器上H:\js目錄下文件flower.zip上傳到FTP服務器
把FTP服務器中的sql.rar文件下載到XP機器上的H:\JS目錄
ftp-get-put.bat內容如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.133.34 >"%ftpfilename%" 
  4. echo lgh >>"%ftpfilename%" 
  5. echo www.liuguohua.com >>"%ftpfilename%" 
  6. echo bin >>"%ftpfilename%" 
  7. echo lcd h:\js >>"%ftpfilename%" 
  8. echo get sql.rar >>"%ftpfilename%" 
  9. echo put flower.zip >>"%ftpfilename%" 
  10. echo bye >>"%ftpfilename%" 
  11. ftp -s:"%ftpfilename%" 
  12. del "%ftpfilename%" 

    我們來看看結果,見下面兩張圖。從XP系統上看,H盤的JS目錄,多了個sql.rar,FTP服務器上的根目錄多了個flower.zip,這說明,剛纔的腳本完成正常的執行了,達到了預期的目的。

 實例三:用put,get上傳,下載多個文件

在XP機器上把flower.zip複製一次,改名爲flower2.zip
在XP機器上把把第二次實例下載的sql.rar文件刪除,以免影響到本次操作
在FTP服務器上把第二次實例上傳的flower.zip文件刪除,以免影響到本次操作
把XP機器上H:\js目錄下文件flower.zip 和flower2.zip上傳到FTP服務器
ftp-get-put-many.bat內容如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.133.34 >"%ftpfilename%" 
  4. echo lgh >>"%ftpfilename%" 
  5. echo www.liuguohua.com >>"%ftpfilename%" 
  6. echo bin >>"%ftpfilename%" 
  7. echo lcd h:\js >>"%ftpfilename%" 
  8. echo put flower.zip flower2.zip>>"%ftpfilename%" 
  9. echo bye >>"%ftpfilename%" 
  10. ftp -s:"%ftpfilename%" 
  11. del "%ftpfilename%" 

   到FTP服務器上查看根目錄,看flower.zip與flower2.zip是否已成功上傳。從圖上看,只成功上傳了flower2.zip文件。

剛那個ftp-get-put-many.bat腳本里
echo put flower.zip flower2.zip>>"%ftpfilename%"
flower2.zip是傳輸的最後一個文件,是不是用put時,意味着bat在處理上傳時,只認最後一個文件呢。我們再多加個文件flower3.zip,來驗證。

在XP機器上把flower.zip複製一次,改名爲flower3.zip
在FTP服務器上把第二次實例上傳的flower2.zip文件刪除,以免影響到本次操作

tp-get-put-many.bat內容修改如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.133.34 >"%ftpfilename%" 
  4. echo lgh >>"%ftpfilename%" 
  5. echo www.liuguohua.com >>"%ftpfilename%" 
  6. echo bin >>"%ftpfilename%" 
  7. echo lcd h:\js >>"%ftpfilename%" 
  8. echo put flower.zip flower2.zip flower3.zip>>"%ftpfilename%" 
  9. echo bye >>"%ftpfilename%" 
  10. ftp -s:"%ftpfilename%" 
  11. del "%ftpfilename%" 

     結果,還是隻成功上傳了flower2.zip,因bat雙擊時,執行過程會一閃而過,我們看不到執行過程,到命令行去執行下,看到底出了什麼問題。

    命令行,執行ftp-get-put-many.bat腳本,從執行情況看,flower.zip三個文件都是put的,但在傳輸時,卻只傳了flower2.zip,真不解,有知道的朋友嗎?給點方向

再換個方式,用通配符*,試試。
ftp-get-put-many.bat內容修改如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.133.34 >"%ftpfilename%" 
  4. echo lgh >>"%ftpfilename%" 
  5. echo www.liuguohua.com >>"%ftpfilename%" 
  6. echo bin >>"%ftpfilename%" 
  7. echo lcd h:\js >>"%ftpfilename%" 
  8. echo put flower*.zip >>"%ftpfilename%" 
  9. echo bye >>"%ftpfilename%" 
  10. ftp -s:"%ftpfilename%" 
  11. del "%ftpfilename%" 

在FTP服務器上把上傳的flower文件全部刪除,以免影響到本次操作
執行ftp-get-put-many.bat,結果只有flower.zip文件上傳成功了。呵,flower3.zip文件,怎麼都不能上傳。???

    其實用put傳輸多個文件,完全可用重複的方式取代,比如:ftp-get-put-many.bat內容修改如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.133.34 >"%ftpfilename%" 
  4. echo lgh >>"%ftpfilename%" 
  5. echo www.liuguohua.com >>"%ftpfilename%" 
  6. echo bin >>"%ftpfilename%" 
  7. echo lcd h:\js >>"%ftpfilename%" 
  8. echo put flower.zip >>"%ftpfilename%" 
  9. echo put flower2.zip >>"%ftpfilename%" 
  10. echo put flower3.zip >>"%ftpfilename%" 
  11. echo bye >>"%ftpfilename%" 
  12. ftp -s:"%ftpfilename%" 
  13. del "%ftpfilename%" 

實例四:用mput,mget上傳,下載多個文件
在FTP服務器上刪除有關flower的文件

ftp-mget-mput-many.bat內容如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.133.34 >"%ftpfilename%" 
  4. echo lgh >>"%ftpfilename%" 
  5. echo www.liuguohua.com >>"%ftpfilename%" 
  6. echo bin >>"%ftpfilename%" 
  7. echo lcd h:\js >>"%ftpfilename%" 
  8. echo mput flower.zip flower2.zip flower3.zip>>"%ftpfilename%" 
  9. echo bye >>"%ftpfilename%" 
  10. ftp -s:"%ftpfilename%" 
  11. del "%ftpfilename%" 

雙擊ftp-mget-mput-many.bat後,發現系統彈出一窗口後,就卡住了,停止不前

原因是用了mput命令,但沒有用Prompt關閉交互

ftp-mget-mput-many.bat內容修改如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.133.34 >"%ftpfilename%" 
  4. echo lgh >>"%ftpfilename%" 
  5. echo www.liuguohua.com >>"%ftpfilename%" 
  6. echo Prompt >>"%ftpfilename%" 
  7. echo bin >>"%ftpfilename%" 
  8. echo lcd h:\js >>"%ftpfilename%" 
  9. echo mput flower.zip flower2.zip flower3.zip>>"%ftpfilename%" 
  10. echo bye >>"%ftpfilename%" 
  11. ftp -s:"%ftpfilename%" 
  12. del "%ftpfilename%" 

再次執行ftp-mget-mput-many.bat,結果見下圖:

用通配符*試試
在FTP服務器上刪除有關flower的文件
ftp-mget-mput-many.bat內容修改如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.133.34 >"%ftpfilename%" 
  4. echo lgh >>"%ftpfilename%" 
  5. echo www.liuguohua.com >>"%ftpfilename%" 
  6. echo Prompt >>"%ftpfilename%" 
  7. echo bin >>"%ftpfilename%" 
  8. echo lcd h:\js >>"%ftpfilename%" 
  9. echo mput flower*.zip >>"%ftpfilename%" 
  10. echo bye >>"%ftpfilename%" 
  11. ftp -s:"%ftpfilename%" 
  12. del "%ftpfilename%" 

照樣成功上傳有關flower*.zip文件。因爲結果與上一步是一樣的,所以就不抓圖了。

實例五:用ascii在windows系統間傳輸非文本文件
把XP電腦上的rmb.jpg通過ascii傳到FTP服務器的根目錄。


ftp-get-ascii.bat內容修改如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.133.34 >"%ftpfilename%" 
  4. echo lgh >>"%ftpfilename%" 
  5. echo www.liuguohua.com >>"%ftpfilename%" 
  6. echo ascii >>"%ftpfilename%" 
  7. echo lcd h:\js >>"%ftpfilename%" 
  8. echo put rmb.jpg>>"%ftpfilename%" 
  9. echo bye >>"%ftpfilename%" 
  10. ftp -s:"%ftpfilename%" 
  11. del "%ftpfilename%" 

     執行ftp-get-ascii.bat後,發現rmb.jpg可以正常上傳,並且可以正常打開,那,這個現象與前面所以的ascii不能傳輸非文本東西有出入,這是怎麼回會事呢。
     這是因爲,FTP服務器是WINDOWS系統,XP電腦上的bat腳本也是在windows系統上運行的,所以bat在windows系統裏用FTP傳輸文件,不管是用ascii,還是用binary,都是可以的。接下來我們再做一個實驗,FTP服務器選centos,再測下ascii傳輸非文本文件問題。

實例六:用ascii在windows系統與linux系統間傳輸非文本文件
在RHEL 5.4 64位系統上建立一vsftpd服務器

    上面說過redhat默認啓用二進制傳輸,關閉了ascii碼傳輸,所以我們還要修改一下vsftpd的配置文件,修改/etc/vsftpd/vsftpd.conf文件,允許客戶端進行ascii傳輸,並重啓vsftpd

把rmb.jpg放到FTP服務器,大家注意下H:\js目錄下只有ftp-getascii.bat文件

 

ftp-getascii.bat文件內容修改如下:
 

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.145.226 >"%ftpfilename%" 
  4. echo ftp1 >>"%ftpfilename%" 
  5. echo redhat >>"%ftpfilename%" 
  6. echo asc >>"%ftpfilename%" 
  7. echo lcd h:\js >>"%ftpfilename%" 
  8. echo get rmb.jpg >>"%ftpfilename%" 
  9. echo bye >>"%ftpfilename%" 
  10. ftp -s:"%ftpfilename%" 
  11. del "%ftpfilename%" 

    執行ftp-getascii.bat,看結果,rmb.jpg文件有下載到XP電腦裏,雙擊這個文件,發現圖像亂碼,文件被破壞了,都是ascii碼傳輸惹的禍。

換bin傳輸,測試一下
在XP電腦上刪除rmb.jpg文件,再雙擊ftp-getascii.bat文件,去從LINUX的FTP服務器下載一個rmb.jpg文件。

修改ftp-getascii.bat,把ascii改給二進制傳輸

  1. @echo off 
  2. set ftpfilename=autoftp.cfg 
  3. echo open 192.168.145.226 >"%ftpfilename%" 
  4. echo ftp1 >>"%ftpfilename%" 
  5. echo redhat >>"%ftpfilename%" 
  6. echo bin >>"%ftpfilename%" 
  7. echo lcd h:\js >>"%ftpfilename%" 
  8. echo get rmb.jpg >>"%ftpfilename%" 
  9. echo bye >>"%ftpfilename%" 
  10. ftp -s:"%ftpfilename%" 
  11. del "%ftpfilename%" 


結果,文件正常下載,圖像也顯示正常。


擴展閱讀:
ftp使用的內部命令如下(中括號表示可選項):
1.![cmd[args]]:在本地機中執行交互shell,exit回到ftp環境,如:!ls*.zip.
2.$ macro-ame[args]:執行宏定義macro-name.
3.account[password]:提供登錄遠程系統成功後訪問系統資源所需的補充口令。
4.append local-file[remote-file]:將本地文件追加到遠程系統主機,若未指定遠程系統文件名,則使用本地文件名。
5.ascii:使用ascii類型傳輸方式。
6.bell:每個命令執行完畢後計算機響鈴一次。
7.bin:使用二進制文件傳輸方式。
8.bye:退出ftp會話過程。
9.case:在使用mget時,將遠程主機文件名中的大寫轉爲小寫字母。
10.cd remote-dir:進入遠程主機目錄。
11.cdup:進入遠程主機目錄的父目錄。
12.chmod mode file-name:將遠程主機文件file-name的存取方式設置爲mode,如: chmod 777 a.out 。
13.close:中斷與遠程服務器的ftp會話(與open對應)。
14.cr:使用asscii方式傳輸文件時,將回車換行轉換爲回行。
15.delete remote-file:刪除遠程主機文件。
16.debug[debug-value]:設置調試方式, 顯示發送至遠程主機的每條命令,如: deb up 3,若設爲0,表示取消debug。
17.dir[remote-dir][local-file]:顯示遠程主機目錄,並將結果存入本地文件local-file。
18.disconnection:同close。
19.form format:將文件傳輸方式設置爲format,缺省爲file方式。
20.get remote-file[local-file]: 將遠程主機的文件remote-file傳至本地硬盤的local-file。
21.glob:設置mdelete,mget,mput的文件名擴展,缺省時不擴展文件名,同命令行的-g參數。
22.hash:每傳輸1024字節,顯示一個hash符號(#)。
23.help[cmd]:顯示ftp內部命令cmd的幫助信息,如:help get。
24.idle[seconds]:將遠程服務器的休眠計時器設爲[seconds]秒。
25.image:設置二進制傳輸方式(同binary)。
26.lcd[dir]:將本地工作目錄切換至dir。
27.ls[remote-dir][local-file]:顯示遠程目錄remote-dir, 並存入本地文件local-file。
28.macdef macro-name:定義一個宏,遇到macdef下的空行時,宏定義結束。
29.mdelete[remote-file]:刪除遠程主機文件。
30.mdir remote-files local-file:與dir類似,但可指定多個遠程文件,如: mdir *.o.*.zipoutfile 。
31.mget remote-files:傳輸多個遠程文件。
32.mkdir dir-name:在遠程主機中建一目錄。
33.mls remote-file local-file:同nlist,但可指定多個文件名。
34.mode[modename]:將文件傳輸方式設置爲modename, 缺省爲stream方式。
35.modtime file-name:顯示遠程主機文件的最後修改時間。
36.mput local-file:將多個文件傳輸至遠程主機。
37.newer file-name: 如果遠程機中file-name的修改時間比本地硬盤同名文件的時間更近,則重傳該文件。
38.nlist[remote-dir][local-file]:顯示遠程主機目錄的文件清單,並存入本地硬盤的local-file。
39.nmap[inpattern outpattern]:設置文件名映射機制, 使得文件傳輸時,文件中的某些字符相互轉換,如:nmap $1.$2.$3[$1,$2].[$2,$3],則傳輸文件a1.a2.a3時,文件名變爲a1,a2。該命令特別適用於遠程主機爲非UNIX
機的情況。
40.ntrans[inchars[outchars]]:設置文件名字符的翻譯機制,如ntrans1R,則文件名LLL將變爲RRR。
41.open host[port]:建立指定ftp服務器連接,可指定連接端口。
42.passive:進入被動傳輸方式。
43.prompt:設置多個文件傳輸時的交互提示。
44.proxy ftp-cmd:在次要控制連接中,執行一條ftp命令, 該命令允許連接兩個ftp服務器,以在兩個服務器間傳輸文件。第一條ftp命令必須爲open,以首先建立兩個服務器間的連接。
45.put local-file[remote-file]:將本地文件local-file傳送至遠程主機。
46.pwd:顯示遠程主機的當前工作目錄。
47.quit:同bye,退出ftp會話。
48.quote arg1,arg2...:將參數逐字發至遠程ftp服務器,如:quote syst.
49.recv remote-file[local-file]:同get。
50.reget remote-file[local-file]:類似於get,但若local-file存在,則從上次傳輸中斷處續傳。
51.rhelp[cmd-name]:請求獲得遠程主機的幫助。
52.rstatus[file-name]:若未指定文件名,則顯示遠程主機的狀態,否則顯示文件狀態。
53.rename[from][to]:更改遠程主機文件名。
54.reset:清除回答隊列。
55.restart marker:從指定的標誌marker處,重新開始get或put,如:restart 130。
56.rmdir dir-name:刪除遠程主機目錄。
57.runique:設置文件名唯一性存儲,若文件存在,則在原文件後加後綴..1,.2等。
58.send local-file[remote-file]:同put。
59.sendport:設置PORT命令的使用。
60.site arg1,arg2...:將參數作爲SITE命令逐字發送至遠程ftp主機。
61.size file-name:顯示遠程主機文件大小,如:site idle 7200。
62.status:顯示當前ftp狀態。
63.struct[struct-name]:將文件傳輸結構設置爲struct-name, 缺省時使用stream結構。
64.sunique:將遠程主機文件名存儲設置爲唯一(與runique對應)。
65.system:顯示遠程主機的操作系統類型。
66.tenex:將文件傳輸類型設置爲TENEX機的所需的類型。
67.tick:設置傳輸時的字節計數器。
68.trace:設置包跟蹤。
69.type[type-name]:設置文件傳輸類型爲type-name,缺省爲ascii,如:type binary,設置二進制傳輸方式。
70.umask[newmask]:將遠程服務器的缺省umask設置爲newmask,如:umask 3。
71.user user-name[password][account]:向遠程主機表明自己的身份,需要口令時,必須輸入口令,如:user anonymous my@email。
72.verbose:同命令行的-v參數,即設置詳盡報告方式,ftp服務器的所有響應都將顯示給用戶,缺省爲on.
73.?[cmd]:同help.

 

本文出自 “系統網絡運維” 博客,請務必保留此出處http://369369.blog.51cto.com/319630/842341

發佈了1 篇原創文章 · 獲贊 6 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章