shell操作典型案例--FTP操作


從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)獲取文件列表

wgetftp-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,轉載請注明出處!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM