很多时候我们需要在脚本里面通过FTP或是其他方式取另外一台机器上的文件,为安全起见而登录另外一台机器一般都需要用户认证。这里的例子在sh脚本中调用expect脚本实现自动交互。

Expect是一个用来实现自动交谈功能的软件,Expect是在TCL语言基础上建立的,它还提供了一些TCL语言所沒有的命令。例如spawn命令启动一个Unix/Linux程序来进行交互的运行,Send命令向程序发送字符串,expect命令等待送进的某些字符串。

expect.sh文件内容: 

----------------------------------------------------------------------------------------------------------------

#!/usr/bin/expect -f


if {[lindex $argv 0] == "getinfo"} {
    set FIRST_TIME "N"
    spawn sftp username@192.168.0.1
    expect {
          "* (yes/no)? " {
              set FIRST_TIME "Y"
              sleep 1
              send "yes/r"
          }
          "* password: " {
              sleep 1
              send "password/r"
          }
          timeout {
              exit 2
          }
   }

   if { "$FIRST_TIME" == "Y" } {
      expect {
             "* password: " {
                 sleep 1
                 send "password/r"
             }
             timeout {
                 exit 2
             }
      }
   }

   expect "sftp> "
   send "ls -all [lindex $argv 1]/r"
   expect "sftp> "
   exit 0
}

if {[lindex $argv 0] == "download"} {
    spawn sftp username@192.168.0.1
    expect {
          "* password: " {
              sleep 1
              send "password/r"
          }
          timeout {
              exit 2
          }
   }

   set timeout -1
   expect "sftp> "
   send "get [lindex $argv 1]/[lindex $argv 2] [lindex $argv 3]/r"
   expect "sftp> "
   exit 0
}
----------------------------------------------------------------------------------------------------------------

这里因为如果一台机器第一次访问另外一台机器时,会显示如下的确认信息:

----------------------------------------------------------------------------------------------------------------

$ sftp username@192.168.0.1

Connecting to 192.168.0.1...
The authenticity of host '192.168.0.1 (192.168.0.1)' can't be established.
RSA key fingerprint is 8a:3e:5b:a2:dd:b1:19:2d:c9:1f:b9:69:96:15:5c:41.
Are you sure you want to continue connecting (yes/no)?

----------------------------------------------------------------------------------------------------------------

但是以后的访问就不会出现这些认证信息,所以使用FIRST_TIME加以区分。

这里实现了两个函数getinfo和download,因为脚本下不能象C++那样调用函数,这里使用通过传参数来选择函数。第一个函数getinfo罗列目标机器上某一目录下的文件,第二个函数download下载目标机器上的文件。

接下来就是sh脚本中如何调用expect了。选择这样在sh中调用expect主要是因为sh功能很强大,可以在sh中实现很多功能,诸如调用sed来处理字符串等。

autodownload.sh文件的内容:

----------------------------------------------------------------------------------------------------------------

#!/bin/bash

EXPECT_SHELL="expect.sh"

TEMP_FILE="serverinfo.tmp"

#get server target directory information and then save it into a temp local file

`exec /usr/bin/expect $WORKING_DIR/$EXPECT_SHELL getinfo $SERVER_SPIDER_DIR > ./$TEMP_FILE`

while read LINE_STR
do

   # your process to get your target file & save the target file name in TARGET_FILE

done < ./$TEMP_FILE

#delete temp file
rm $TEMP_FILE

# download the target file

$DOWNLOAD_PLACE=./

`exec /usr/bin/expect ./$EXPECT_SHELL download $TARGET_FILE $DOWNLOAD_PLACE > /dev/null`

...

exit 0

----------------------------------------------------------------------------------------------------------------

 

2007/11/14

Logo

更多推荐