Expect 脚本,用于获取ftp的整个目录
点击(此处)折叠或打开
- #!/usr/bin/expect --
- source ~/src/script/log_enable.expect
- proc Usage {name} {
- puts "$name ip:port user pswd rdir \[pattern]"
- puts "Where:"
- puts " ip:port - the ftp addr and port"
- puts " user - user name"
- puts " pswd - passord"
- puts " pattern - only downoad files which match this pattern"
- puts "Example:"
- puts " $name 172.21.128.21 rmtlab rmtlab 5801.272p10 '\[tT]est\[sS]ummary.log'"
- }
- if { $argc < 4 } {
- puts "Invalid argument."
- Usage $argv0
- exit 1
- }
- set addr [lindex $argv 0]
- regsub ":" $addr " " addr
- set user [lindex $argv 1]
- set pswd [lindex $argv 2]
- set rdir [lindex $argv 3]
- if { $argc >= 4 } {
- set patn [lindex $argv 4]
- #TODO:
- # if no file match the pattern under a directory and its sub directories,
- # no need to create the directory and hence the sub directories.
- } else {
- set patn ""
- }
- send_user -- "addr: $addr\r\n"
- send_user -- "user: $user\r\n"
- send_user -- "pswd: $pswd\r\n"
- send_user -- "rdir: $rdir\r\n"
- send_user -- "patn: $patn\r\n"
- proc ftp_get_tree { rdir } {
- global patn
- set timeout 10
- set elem_list_f {}
- set elem_list_d {}
- set ldir $rdir
- puts "$rdir $ldir"
- #0. clear context
- expect "*"
- send -- "\r"
- expect -re ".*\[\r\n]\{2\}ftp>"
- #1. get old dir
- send -- "pwd\r"
- expect -re "\[0-9]+\\s+\"(.+)\"\\s+is current directory.\[\r\n]\{2\}"
- set o_rdir $expect_out(1,string)
- send_user -- "wqc: old rdir: $o_rdir\r\n"
- expect "ftp>"
- set o_ldir [pwd]
- send_user -- "wqc: old ldir: $o_ldir\r\n"
- #2. change to new dir
- send -- "cd $rdir\r"
- expect "ftp>"
- ## if local dir exist
- if { [file exists $ldir ] } {
- if { [file isdirectory $ldir ] } {
- send_user -- "wqc: dir $ldir already exist\r\n"
- } else {
- send_user -- "wqc: '$ldir' exist but is not dir, abort\r\n"
- exit 1
- }
- } else {
- exec mkdir -p $ldir
- exec sync
- }
- cd $ldir
- send -- "lcd $ldir\r"
- expect "ftp>"
- ## check current dir
- ## send -- "pwd\r"
- ## expect -re "\[0-9]+\\s+\"(.+)\"\\s+is current directory.\[\r\n]\{2\}"
- ## set n_rdir $expect_out(1,string)
- ## send_user -- "wqc: new rdir: $n_rdir\r\n"
- ## expect "ftp>"
- ## set n_ldir [pwd]
- ## send_user -- "wqc: new ldir: $n_ldir\r\n"
- #3. get rdir contents
- send -- "ls\r"
- expect {
- -re "^\[d-]\[drwx-]+\[^\r\n]+\[\r\n]\{2\}" {
- set type ""
- set name ""
- ## send_user -- "wqc: $expect_out(buffer)\r\n"
- set ret [regexp "(^.)\[rwx-]+\\s+.+\\s+(\[^\\s]+)\[\r\n]\{2\}" $expect_out(buffer) ignore type name]
- if { $ret == 1 } {
- ## send_user -- "wqc: $type $name\r\n"
- if { $type == "d" } {
- lappend elem_list_d "$name"
- } elseif { $type == "-" } {
- if { $patn != "" } {
- set ret [regexp $patn $name ignore]
- if { $ret == 1 } {
- lappend elem_list_f "$name"
- }
- } else {
- lappend elem_list_f "$name"
- }
- } else {
- send_user "wqc: Unidentified type '$type'\r\n"
- }
- } else {
- send_user -- "wqc: failed $expect_out(buffer)\r\n"
- }
- exp_continue
- }
- -re "\[\r\n]\{2\}" {
- exp_continue
- }
- -re "ftp>" {
- send_user -- "wqc: exec ls done\r\n"
- }
- }
- #4. download files first
- foreach E $elem_list_f {
- send_user "wqc: get file: $E\r\n"
- send -- "\r"
- expect -re ".*\[\r\n]\{2\}ftp>"
- set timeout 3600
- send -- "get $E\r"
- expect -re ".*\[\r\n]\{2\}ftp>"
- set timeout 10
- }
- #5. download sub-dirs
- foreach E $elem_list_d {
- send_user "wqc: get dir : $E\r\n"
- send -- "\r"
- expect -re ".*\[\r\n]\{2\}ftp>"
- ftp_get_tree $E
- }
- #6. change back to old dir
- cd $o_ldir
- send -- "lcd $o_ldir\r"
- expect -- "ftp>"
- send -- "cd $o_rdir\r"
- expect "ftp>"
- ## send -- "pwd\r"
- ## expect -re "\[0-9]+\\s+\"(.+)\"\\s+is current directory.\[\r\n]\{2\}"
- ## set x_rdir $expect_out(1,string)
- ## send_user -- "wqc: exit rdir: $x_rdir\r\n"
- ## expect "ftp>"
- ## set x_ldir [pwd]
- ## send_user -- "wqc: exit ldir: $x_ldir\r\n"
- }
- # $ !ftp
- # ftp 172.21.128.21
- # Connected to 172.21.128.21:21.
- # 220 andd021 FTP server ready.
- # Name (172.21.128.21:21:qingchwa): rmtlab
- # 331 Password required for rmtlab.
- # Password:
- # 230 User rmtlab logged in.
- # Remote system type is UNIX.
- # Using binary mode to transfer files.
- # ftp> ls
- set ldir $rdir
- if { [file exists $ldir ] } {
- if { [file isdirectory $ldir ] } {
- send_user -- "wqc: dir $ldir already exist\r\n"
- } else {
- send_user -- "wqc: '$ldir' exist but is not dir, abort\r\n"
- exit 1
- }
- } else {
- exec mkdir -p $ldir
- exec sync
- }
- cd $ldir
- set timeout 10
- spawn ftp $addr
- expect {
- "Name *:" {
- send -- "$user\r"
- }
- "unknown host" {
- exit 1
- }
- }
- expect "Password:"
- send -- "$pswd\r"
- expect {
- "User $user logged in" {
- }
- "Login failed" {
- exit 2
- }
- }
- expect "ftp>"
- send -- "cd $rdir\r"
- expect "ftp>"
- ftp_get_tree "."
- send -- "quit\r"