從FTP服務器上下載文件或上傳文件到FTP服務器是生產環境中比較常見的場景之一。
shell操作FTP的方式整理如下:
思路一:使用shell調用ftp等客戶端
使用FTP方式,通過shell調用ftp等客戶端,從而完成FTP文件的上傳、下載等操作。
方式一:ftp方式
一個基本的ftp工具,需安裝ftp(yum -y install ftp,后同)。一個樣例如下:
########################################################### ##函數功能:FTP上傳、下載多個文件、單個文件 ##使用示例: ## DownloadFiles #直接調用,不記錄日志 ## #記錄日志,將輸出追加到日志文件即可
## 可以根據需要,在文件名、目錄名等處拼接日期、批次號等內容。 ########################################################### IP="" #FTP服務器地址 PORT="" #FTP端口號 USER="" #FTP用戶名 PWD="" #FTP用戶密碼 REMOTE_DIR="" #遠程FTP服務器目錄 LOC_DIR="" #對應的本地服務器目錄 DEST_FILES="" #遠程FTP服務器文件 DownloadFiles(){ ftp -ivn << EOF #-n 不受.netrc文件的影響,表示禁止自動登錄到初始連接(ftp默認為讀取.netrc文件中的設定) #-i表示在多個文件傳輸期間關閉交互提示 #-v open $IP $PORT user $USER $PWD bin #bin等價於bi,binary等,表示以二進制方式傳輸,另一種方式是ascii #passive表示設置為被動模式的FTP #prompt #被動模式的FTP通常用在處於防火牆之后的FTP客戶訪問外界FTP服務器的情況. #主動模式的FTP是指服務器主動連接客戶端的數據端口,被動模式的FTP是指服務器被動地等待客戶端連接自己的數據端口 #被動模式的FTP通常用在處於防火牆之后的FTP客戶訪問外界FTP服務器的情況. #因為在這種情況下,防火牆通常配置為不允許外界訪問防火牆之后主機,而只允許由防火牆之后的主機發起的連接請求通過. #因此在這種情況下不能使用主動模式的FTP傳輸,而被動模式的FTP可以良好的工作. cd $REMOTE_DIR lcd $LOC_DIR mget $DEST_FILES #多個文件的下載 #get $DEST_FILE_NAME $LOC_FILE_NAME #單個文件的下載 close quit #或bye EOF } UploadFiles(){ ftp -ivn << EOF open $IP $PORT user $USER $PWD bin #passive 可選 cd $REMOTE_DIR lcd $LOC_DIR mput $DEST_FILES #多個文件的上傳 #put $LOC_FILE_NAME $DEST_FILE_NAME #單個文件的上傳 close quit EOF }
方式二:sftp方式
sftp是一款交互式的文件傳輸程序,命令的運行和使用方式與ftp命令相似,但是,sftp命令對傳輸的所有信息使用ssh加密,它還支持公鑰認證和壓縮等功能,安全性更好。使用sftp必須安裝openSSH組件,它是依賴於ssh服務的。
使用sftp時,若沒有配置ssh免密碼登陸,往往需要讓腳步自動輸入密碼,為此需要安裝expect或sshpass組件,使用時,有三種方式:
方法一:使用expect
第一種方式:在bash中直接使用代碼塊:
#!/bin/bash #yum -y install expect #使用expect組件需要手動安裝 #yum -y install tcl USER="" HOST="" PASSWD="" DEST_DIR="" LOC_DIR="" expect<<-END spawn sftp $USER@$HOST expect { "(yes/no)?" { send "yes\r" } "*assword:" {send "${PASSWD}\r"} } expect "sftp>" send "cd ${DEST_DIR}\n" expect "sftp>" send "lcd ${LOC_DIR}\r" expect "sftp>" send "mget *\r" expect "sftp>" send "quit\r" END
第二種方式:將使用expect自動讀入密碼與ftp交互部分作為一個單獨的腳本,然后在其它腳本中調用
#!/usr/bin/expect #設置參數 set USER [lindex $argv 0] set HOST [lindex $argv 1] set PASSWD [lindex $argv 2] set DEST_DIR [lindex $argv 3] set LOC_DIR [lindex $argv 4] #上傳文件到FTP服務器 spawn sftp $USER@$HOST expect { "(yes/no)?" { send "yes\r" } "*assword:" {send "${PASSWD}\r"} } expect "sftp>" send "cd $DEST_DIR\n" expect "sftp>" send "mkdir $DATE_TIME\r" expect "sftp>" send "cd $DEST_DIR\r" expect "sftp>" send "lcd $LOC_DIR\r" expect "sftp>" send "mput *\r" expect "sftp>" send "quit\r" expect eof
call_ftp.sh中調用該腳本部分示例如下:
/usr/bin/expect 腳本路徑/exp_ftp.sh $USER $HOST $PASSWD $DEST_DIR $LOC_DIR
使用位置參數傳遞ftp信息,注意腳本中要寫解析器的絕對路徑,腳本的絕對路徑(推薦)
方法二:使用sshpass
第三種方式:安裝使用sshpass
#!/bin/bash yum -y install sshpass HOST="" FTP_USER="" FTP_PASSWD="" export SSHPASS=$FTP_PASSWD sshpass -e sftp -oBatchMode=no -b - $FTP_USER@$HOST << END ls / bye END
方式三:lftp方式
lftp 是一個功能強大的下載工具,它支持訪問文件的協議: ftp, ftps, http, https, hftp, fish.(其中ftps和https需要在編譯的時候包含openssl庫)。llftp的界面非常像一個shell: 有命令補全,歷史記錄,允許多個后台任務執行等功能,使用起來非常方便。它還有書簽、排隊、鏡像、斷點續傳、多進程下載等功能。
需安裝lftp。
示例如下:
(1)單獨使用lftp
#!bin/bash export NLS_LANG=american_america.AL32UTF8 #設置字符集 HOST="" USER="" PASSWD="" LOC_DIR="" DEST_DIR="" /usr/sbin/lftp << EOF open ftp://$USER:$PASSWD@$HOST mirror -R $LOC_DIR $DEST_DIR #上傳同步文件 mirror -vn $DEST_DIR $LOC_DIR #下載文件 close exit EOF
(2)lftp與sftp混合使用
#!/bin/bash #yum -y install lftp openssh lftp -u ${USER},${PWD} sftp://${IP}:${PORT} <<EOF #端口為可選參數,sftp默認端口為22 cd [FTP服務器目錄] lcd [本地目錄] mget/mput/get/put.. bye EOF
注:幾種ftp客戶端使用方式大致相同,使用時可以使用help命令查看使用幫助,help 命令名稱參考命令參數等方法幫助完成腳本的編寫。
思路二:直接遠程復制
根據FTP服務的本質是針對文件的,因此考慮像操作文件一樣,直接遠程復制、移動
方式四:scp/rsync方式
(1)scp
與sftp類似,依賴ssh服務,支持加密傳輸。有點:安全性好,耗費資源少。使用格式:
scp [參數] [源路徑] [目標路徑] #路徑的完整格式:$USER@HOST:$DIR
本地路徑和遠程路徑都可以做源端或者目標端。樣例如下:
#!/usr/bin/expect . ~/.bash_profile ################################################################# ##調用方法: ## /usr/bin/expect 本腳本路徑 $SRC_DIR $USER ...(參數列表) ################################################################# set SRC_DIR [lindex $argv 0] set USER [lindex $argv 1] set HOST [lindex $argv 2] set src_file [lindex $argv 3] set PWD [lindex $argv 4] spawn scp -r $SRC_DIR $USER@$HOST:$DEST_DIR expect { "(yes/no)?" { send "yes\n" expect "*assword:" { send "$PWD\n"} }
注意:1、注意*的使用
scp -r $LOC_DIR/* $DEST_USER@$DEST_HOST:$DEST_DIR 對拷文件夾下所有文件 (不包括文件夾本身) scp -r $LOC_DIR $DEST_USER@$DEST_HOST:$DEST_DIR 對拷文件夾下所有文件 (包括文件夾本身)
2、若目標端的文件、目錄等與源端名稱相同,會覆蓋
3、使用scp遠程復制文件時,會要求輸入密碼,一種方法是設置ssh免密碼登錄。否則,需要安裝並使用expect工具,讓shell自動輸入密碼。
(2)rsync
Rsync(Remote Synchronize) 是一個遠程資料同步工具,可通過LAN/WAN快速同步多台主機,Rsync使用所為的“Rsync演算法”來使本地主機和遠程主機之間達到同步,這個演算法並不是每次都整份傳送,它只傳送兩台計算機之間所備份的資料不同的部分(增量備份),因此速度相當快。
Rsync的優點如下:
1、可以鏡像保存整個目錄樹和文件系統。
2、可以很容易的做到保持原來文件的許可權、時間、軟鏈接等。
3、無須特使許可權即可安裝。
4、擁有優化的流程,文件傳輸效率高。
5、可以使用Rsh、SSH等方式來傳輸文件,當然也可以直接通過Socket連接。
6、支持匿名傳輸。
另外,與SCP相比,傳輸速度不是一個層次級的。我們在局域網時經常用Rsync和SCP傳輸大量Mysql數據,發現Rsync至少比Scp快20倍以上,所以大家如果需要在Linux/Unix服務器之間互傳海量資料,Rsync是非常好的選擇。當然,當有大量小文件時,rsync會導致磁盤IO負載很高,而scp基本則影響很小。
使用方法:
rsync [可選參數] 源端 目標端
思考:
若rsync需要處理的文件極多,數量極大,並且需定時處理增量,這種情況下,rsync會先掃描全部文件,然后才會進行增量處理,顯然,這個掃描過程是極為消耗資源的,這種情況應該怎么辦呢?
參考:rsync參考:http://www.cnblogs.com/suihui/p/3799638.html
scp參考:http://www.cnblogs.com/peida/archive/2013/03/15/2960802.html
思路三:操作ftp的文件地址的URL
ftp文件地址URL結構:
1)完全格式: ftp://username:password@hostname:port/子目錄或文件
2)快捷格式: ftp://username@hostname/子目錄或文件
使用ftp的URL地址時的注意事項:
1)防止URL中有特殊字符,可以使用雙引號"URL"
2)ftp用戶的密碼、URL等內容中可能包含某些特殊字符,使用時,可能會報錯“-bash: !ifewbprint: event not found”,這時,將該內容用單引號括起來即可。
說明:Bash雙引號里面使用感嘆號(!)就會出現 bash: !: event not found --這樣的錯誤信息 然而換成單引號就沒問題這是因為Bash里面稱單引號為強
引號,稱雙引號為弱引號,而特殊字符是不會在強引號里面進行翻譯的,只在弱引號里面進行翻譯。而感嘆號(!)恰巧是Bash的特殊字符,表示進行歷史替換,而
歷史命令里沒有\n這個命令
參考:http://dusong1992.blog.163.com/blog/static/120930552201251710735240/
方式五:curl方式
curl可以在shell下輕松上傳下載ftp上的文件,相比ftp命令更具有優勢,因為它能在單命令條件下,下載或者上傳一個ftp文件,甚至可以刪除文件。
需安裝curl。
(1)列出FTP服務器上的文件/目錄列表:
curl ftp://malu.me/ --user name:passwd curl ftp://malu.me/ –u name:passwd #簡潔寫法 curl ftp://name:passwd@malu.me #簡潔寫法2
(2)只列出目錄,不顯示進度條:
curl ftp://malu.me –u name:passwd -s
(3)下載單個文件:
curl ftp://malu.me/size.zip –u name:passwd -o size.zip
(4)上傳單個文件:
curl –u name:passwd -T size.mp3 ftp://malu.me/mp3/
(5)從服務器上刪除文件(使用curl傳遞ftp協議的DELE命令)
curl –u name:passwd ftp://malu.me/ -X 'DELE mp3/size.mp3'
(6)下載多個文件
curl不支持遞歸下載,不過可以用數組方式下載文件,比如我們要下載1-10.gif連續命名的文件:
curl –u name:passwd ftp://malu.me/img/[1-10].gif –O #O字母大寫
要連續下載多個文件:
curl –u name:passwd ftp://malu.me/img/[one,two,three].jpg –O #O字母大寫
參考:使用curl下載上傳ftp | 陋室博客 http://bolg.malu.me/html/2011/1239.html
方式六:wget方式
wget是一個命令行下的下載工具,體積小但功能完善,它支持斷點下載功能,同時支持FTP和HTTP下載方式,支持代理服務器和設置起來方便簡單。可以據此實現部分ftp功能。需安裝wget,效率上比ftp工具快。
(1)獲取文件列表
wget –ftp-user=$USERNAME –ftp-password=$PASSWORD url --no-remove-listing wget --spider URL --no-remove-listing #此處使用ftpURL的完整格式:ftp://$USERNAME:$PASSWORD@$HOST/$DEST_FILE_LIST
#--no-remove-listing 保存監聽文件,獲取ftp文件列表的html文件
(2)下載文件
樣例1:
wget -r url -P $LOC_DIR -nH --cut-dirs=n #url中包含用戶名、密碼 加上 --cut-dirs=n 忽略n個目錄,從FTP服務器根目錄算起第幾層目錄 加上 -P dir 指定本地文件夾dir
樣例2:
wget -nH -m --ftp-user=$USER --ftp-password=$PWD URL -nH:不創建以主機名命名的目錄。 –cut-dirs:希望去掉原來的目錄層數,從根目錄開始計算。如果想完全保留FTP原有的目錄結構,則不要加該參數。 -m:下載所有子目錄並且保留目錄結構。
參考:http://www.jb51.net/LINUXjishu/86326.html
本文作者原始鏈接:http://www.cnblogs.com/chinas/p/6957701.html,轉載請注明出處!!!