Expect 脚本,用于获取ftp的整个目录

点击(此处)折叠或打开

  1. #!/usr/bin/expect --

  2. source ~/src/script/log_enable.expect

  3. proc Usage {name} {
  4.     puts "$name ip:port user pswd rdir \[pattern]"
  5.     puts "Where:"
  6.     puts " ip:port - the ftp addr and port"
  7.     puts " user - user name"
  8.     puts " pswd - passord"
  9.     puts " pattern - only downoad files which match this pattern"
  10.     puts "Example:"
  11.     puts " $name 172.21.128.21 rmtlab rmtlab 5801.272p10 '\[tT]est\[sS]ummary.log'"
  12. }
  13. if { $argc < 4 } {
  14.     puts "Invalid argument."
  15.     Usage $argv0
  16.     exit 1
  17. }

  18. set addr [lindex $argv 0]
  19. regsub ":" $addr " " addr
  20. set user [lindex $argv 1]
  21. set pswd [lindex $argv 2]
  22. set rdir [lindex $argv 3]
  23. if { $argc >= 4 } {
  24.     set patn [lindex $argv 4]
  25.     #TODO:
  26.     # if no file match the pattern under a directory and its sub directories,
  27.     # no need to create the directory and hence the sub directories.
  28. } else {
  29.     set patn ""
  30. }
  31. send_user -- "addr: $addr\r\n"
  32. send_user -- "user: $user\r\n"
  33. send_user -- "pswd: $pswd\r\n"
  34. send_user -- "rdir: $rdir\r\n"
  35. send_user -- "patn: $patn\r\n"

  36. proc ftp_get_tree { rdir } {
  37.     global patn

  38.     set timeout 10

  39.     set elem_list_f {}
  40.     set elem_list_d {}
  41.     set ldir $rdir


  42.     puts "$rdir $ldir"

  43.     #0. clear context
  44.     expect "*"
  45.     send -- "\r"
  46.     expect -re ".*\[\r\n]\{2\}ftp>"

  47.     #1. get old dir
  48.     send -- "pwd\r"
  49.     expect -re "\[0-9]+\\s+\"(.+)\"\\s+is current directory.\[\r\n]\{2\}"
  50.     set o_rdir $expect_out(1,string)
  51.     send_user -- "wqc: old rdir: $o_rdir\r\n"
  52.     expect "ftp>"

  53.     set o_ldir [pwd]
  54.     send_user -- "wqc: old ldir: $o_ldir\r\n"

  55.     #2. change to new dir
  56.     send -- "cd $rdir\r"
  57.     expect "ftp>"

  58.     ## if local dir exist
  59.     if { [file exists $ldir ] } {
  60.         if { [file isdirectory $ldir ] } {
  61.             send_user -- "wqc: dir $ldir already exist\r\n"
  62.         } else {
  63.             send_user -- "wqc: '$ldir' exist but is not dir, abort\r\n"
  64.             exit 1
  65.         }
  66.     } else {
  67.         exec mkdir -p $ldir
  68.         exec sync
  69.     }
  70.     cd $ldir
  71.     send -- "lcd $ldir\r"
  72.     expect "ftp>"

  73.     ## check current dir
  74.     ## send -- "pwd\r"
  75.     ## expect -re "\[0-9]+\\s+\"(.+)\"\\s+is current directory.\[\r\n]\{2\}"
  76.     ## set n_rdir $expect_out(1,string)
  77.     ## send_user -- "wqc: new rdir: $n_rdir\r\n"
  78.     ## expect "ftp>"

  79.     ## set n_ldir [pwd]
  80.     ## send_user -- "wqc: new ldir: $n_ldir\r\n"

  81.     #3. get rdir contents
  82.     send -- "ls\r"
  83.     expect {
  84.         -re "^\[d-]\[drwx-]+\[^\r\n]+\[\r\n]\{2\}" {
  85.             set type ""
  86.             set name ""
  87.             ## send_user -- "wqc: $expect_out(buffer)\r\n"
  88.             set ret [regexp "(^.)\[rwx-]+\\s+.+\\s+(\[^\\s]+)\[\r\n]\{2\}" $expect_out(buffer) ignore type name]
  89.             if { $ret == 1 } {
  90.                 ## send_user -- "wqc: $type $name\r\n"
  91.                 if { $type == "d" } {
  92.                     lappend elem_list_d "$name"
  93.                 } elseif { $type == "-" } {
  94.                     if { $patn != "" } {
  95.                         set ret [regexp $patn $name ignore]
  96.                         if { $ret == 1 } {
  97.                             lappend elem_list_f "$name"
  98.                         }
  99.                     } else {
  100.                         lappend elem_list_f "$name"
  101.                     }
  102.                 } else {
  103.                     send_user "wqc: Unidentified type '$type'\r\n"
  104.                 }

  105.             } else {
  106.                 send_user -- "wqc: failed $expect_out(buffer)\r\n"
  107.             }
  108.             exp_continue
  109.         }
  110.         -re "\[\r\n]\{2\}" {
  111.             exp_continue
  112.         }
  113.         -re "ftp>" {
  114.             send_user -- "wqc: exec ls done\r\n"
  115.         }
  116.     }

  117.     #4. download files first
  118.     foreach E $elem_list_f {
  119.         send_user "wqc: get file: $E\r\n"
  120.         send -- "\r"
  121.         expect -re ".*\[\r\n]\{2\}ftp>"

  122.         set timeout 3600
  123.         send -- "get $E\r"
  124.         expect -re ".*\[\r\n]\{2\}ftp>"
  125.         set timeout 10
  126.     }

  127.     #5. download sub-dirs
  128.     foreach E $elem_list_d {
  129.         send_user "wqc: get dir : $E\r\n"
  130.         send -- "\r"
  131.         expect -re ".*\[\r\n]\{2\}ftp>"

  132.         ftp_get_tree $E
  133.     }

  134.     #6. change back to old dir
  135.     cd $o_ldir
  136.     send -- "lcd $o_ldir\r"
  137.     expect -- "ftp>"

  138.     send -- "cd $o_rdir\r"
  139.     expect "ftp>"

  140.     ## send -- "pwd\r"
  141.     ## expect -re "\[0-9]+\\s+\"(.+)\"\\s+is current directory.\[\r\n]\{2\}"
  142.     ## set x_rdir $expect_out(1,string)
  143.     ## send_user -- "wqc: exit rdir: $x_rdir\r\n"
  144.     ## expect "ftp>"

  145.     ## set x_ldir [pwd]
  146.     ## send_user -- "wqc: exit ldir: $x_ldir\r\n"
  147. }

  148. # $ !ftp
  149. # ftp 172.21.128.21
  150. # Connected to 172.21.128.21:21.
  151. # 220 andd021 FTP server ready.
  152. # Name (172.21.128.21:21:qingchwa): rmtlab
  153. # 331 Password required for rmtlab.
  154. # Password:
  155. # 230 User rmtlab logged in.
  156. # Remote system type is UNIX.
  157. # Using binary mode to transfer files.
  158. # ftp> ls
  159. set ldir $rdir
  160. if { [file exists $ldir ] } {
  161.     if { [file isdirectory $ldir ] } {
  162.         send_user -- "wqc: dir $ldir already exist\r\n"
  163.     } else {
  164.         send_user -- "wqc: '$ldir' exist but is not dir, abort\r\n"
  165.         exit 1
  166.     }
  167. } else {
  168.     exec mkdir -p $ldir
  169.     exec sync
  170. }
  171. cd $ldir

  172. set timeout 10

  173. spawn ftp $addr
  174. expect {
  175.     "Name *:" {
  176.         send -- "$user\r"
  177.     }
  178.     "unknown host" {
  179.         exit 1
  180.     }
  181. }

  182. expect "Password:"
  183. send -- "$pswd\r"

  184. expect {
  185.     "User $user logged in" {
  186.     }
  187.     "Login failed" {
  188.         exit 2
  189.     }
  190. }
  191. expect "ftp>"

  192. send -- "cd $rdir\r"
  193. expect "ftp>"
  194. ftp_get_tree "."

  195. send -- "quit\r"


10-02 10:23