为SFTP创建外部命令集

时间:2011-11-09 13:53:15

标签: tcl sftp expect

目前我有一些代码通过expect / tcl进行SFTP。它是这样的:

send -i $ftpid "$cmd\r"
expect {
    -i $ftpid -re "\n5\[0-9]\[0-9] \[^bB].*\nsftp> " {
        set errorCode 149
        set errorInfo "SFTP command error on $cmd."
        return 1
    }
    -i $ftpid "452 Err.*\nsftp> " {
        set errorCode 149
        set errorInfo "SFTP 452 command error on $cmd."
        return 1
    }
    -i $ftpid "Invalid command*\nsftp> " {
        set errorCode 149
        set errorInfo "SFTP invalid command on $cmd."
        return 1
    }
    -i $ftpid -re "\n2\[0-9]\[0-9] .*\nsftp> " {
        return 0
    }
}

偶尔我会遇到FTP服务器的返回代码或消息与代码库中已填充的内容不匹配的情况。我想要做的就是有一个外部文件(例如:returncodes.tbl)而不是修改核心代码,我可以在其中找到一些消息列表,如:

552 Invalid Return*\nsftp>;<errorCode>;<errorInfo>
400 Some Error*\nsftp>;<errorCode>;<errorInfo>
...

然后它将在期望代码中解释它,如:

-i $ftpid "552 Invalid Return*\nsftp>" {
    set errorCode <errorCode>
    set errorInfo "<errorInfo>"
    return 1
}
-i $ftpid "400 Some Error*\nsftp>" {
    set errorCode <errorCode>
    set errorInfo "<errorInfo>"
    return 1
}

我知道如何读取外部文件并将变量打开(打开/读取/拆分)。但是我无法弄清楚如何在expect语句中创建所需的循环。希望有人可能知道如何实现这一目标。

1 个答案:

答案 0 :(得分:2)

我想通过在现有expect语句的末尾构建一个可以捕获模式并用正则表达式解析它的案例来解决这个问题。然后你只需要一个for循环来清除文件并阻止匹配。

您可能需要使用正则表达式才能使其正常工作 - 再次发送\ r \ n将对齐期望缓冲区,以便您可以捕获错误代码。

(我不知道你是如何加载文件的,所以现在我假设它是一个由“\ n”和“;”拆分的平面列表)

expect {
     #your existing expect code here

    -i $ftpid -re "\[0-9]{3}.*\\*\nsftp>" {
        send -i $ftpid "\r"
        expect -i $ftpid "sftp>"
        regexp "^(.*\nsftp>)\nsftp>" $expect_out(buffer) garbage errorMsg
        set index 0
        foreach element $filelistyouloaded {
            if { $element == $errorMsg } { 
                 set errorCode $filelistyouloaded([expr $index + 1])
                 set errorInfo $filelistyouloaded([expr $index + 2])
                 return 1
            }
            incr index
        }
    }        

}