Bat指令碼處理ftp超強案例分析_DOS/BAT

來源:互聯網
上載者:User
前言:
公司有幾百台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.jb51.net。該使用者的根目錄為D:\lgh。裡面檔案見下圖。sql.rar是sql.bat的壓縮檔,大家注意看圖,我等下會在後面的執行個體中引用這個檔案,把mget,get,prompt,bin,ascii等ftp命令詮釋得一清二白。

 

執行個體一:直接BAT調用FTP命令

ftpbat.bat內容
(***大家建立bat檔案不要命名為ftp.bat,執行時會有問題***)
複製代碼 代碼如下:

ftp
open 192.168.133.34
lgh
www.jb51.net
get sql.rar
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內容如下:
複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.133.34 >"%ftpfilename%"
echo lgh >>"%ftpfilename%"
echo www.liuguohua.com >>"%ftpfilename%"
echo bin >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo get sql.rar >>"%ftpfilename%"
echo put flower.zip >>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
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內容如下:
複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.133.34 >"%ftpfilename%"
echo lgh >>"%ftpfilename%"
echo www.liuguohua.com >>"%ftpfilename%"
echo bin >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo put flower.zip flower2.zip>>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
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檔案刪除,以免影響到本次操作

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


複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.133.34 >"%ftpfilename%"
echo lgh >>"%ftpfilename%"
echo www.liuguohua.com >>"%ftpfilename%"
echo bin >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo put flower.zip flower2.zip flower3.zip>>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
del "%ftpfilename%"


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

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

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


複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.133.34 >"%ftpfilename%"
echo lgh >>"%ftpfilename%"
echo www.liuguohua.com >>"%ftpfilename%"
echo bin >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo put flower*.zip >>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
del "%ftpfilename%"


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

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

複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.133.34 >"%ftpfilename%"
echo lgh >>"%ftpfilename%"
echo www.liuguohua.com >>"%ftpfilename%"
echo bin >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo put flower.zip >>"%ftpfilename%"
echo put flower2.zip >>"%ftpfilename%"
echo put flower3.zip >>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
del "%ftpfilename%"


執行個體四:用mput,mget上傳,下載多個檔案

在FTP伺服器上刪除有關flower的檔案

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

複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.133.34 >"%ftpfilename%"
echo lgh >>"%ftpfilename%"
echo www.liuguohua.com >>"%ftpfilename%"
echo bin >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo mput flower.zip flower2.zip flower3.zip>>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
del "%ftpfilename%"


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

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

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

複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.133.34 >"%ftpfilename%"
echo lgh >>"%ftpfilename%"
echo www.liuguohua.com >>"%ftpfilename%"
echo Prompt >>"%ftpfilename%"
echo bin >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo mput flower.zip flower2.zip flower3.zip>>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
del "%ftpfilename%"


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

用萬用字元*試試
在FTP伺服器上刪除有關flower的檔案
ftp-mget-mput-many.bat內容修改如下:


複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.133.34 >"%ftpfilename%"
echo lgh >>"%ftpfilename%"
echo www.liuguohua.com >>"%ftpfilename%"
echo Prompt >>"%ftpfilename%"
echo bin >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo mput flower*.zip >>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
del "%ftpfilename%"


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

執行個體五:用ascii在windows系統間傳輸非文字檔

把XP電腦上的rmb.jpg通過ascii傳到FTP伺服器的根目錄。


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


複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.133.34 >"%ftpfilename%"
echo lgh >>"%ftpfilename%"
echo www.liuguohua.com >>"%ftpfilename%"
echo ascii >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo put rmb.jpg>>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
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檔案內容修改如下:

複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.145.226 >"%ftpfilename%"
echo ftp1 >>"%ftpfilename%"
echo redhat >>"%ftpfilename%"
echo asc >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo get rmb.jpg >>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
del "%ftpfilename%"


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

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

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

複製代碼 代碼如下:

@echo off
set ftpfilename=autoftp.cfg
echo open 192.168.145.226 >"%ftpfilename%"
echo ftp1 >>"%ftpfilename%"
echo redhat >>"%ftpfilename%"
echo bin >>"%ftpfilename%"
echo lcd h:\js >>"%ftpfilename%"
echo get rmb.jpg >>"%ftpfilename%"
echo bye >>"%ftpfilename%"
ftp -s:"%ftpfilename%"
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.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.