Tcl 在Expect For SFTP中创建外部命令集

Tcl 在Expect For SFTP中创建外部命令集,tcl,sftp,expect,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

目前,我有一些代码正在通过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>
...
552无效返回*\nsftp>;;
400一些错误*\nsftp>;;
...
因此,它将在expect代码中解释它,如下所示:

-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
}
-i$ftpid“552无效返回*\nsftp>”{
设置错误代码
设置错误信息“”
返回1
}
-i$ftpid“400某些错误*\nsftp>”{
设置错误代码
设置错误信息“”
返回1
}

我知道如何读取外部文件并切碎变量(打开/读取/拆分)。但是,我不知道如何在expect语句中创建所需的循环。我希望有人能想到如何实现这一点。

我想我会在现有expect语句的末尾构建一个案例,该案例可以捕获模式并用regexp解析它。然后,您只需要一个for循环来清除文件并找到匹配项

您可能需要使用regexp使其正常工作-再次发送\r将对齐expect缓冲区,以便捕获错误代码

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


+一个问得很好的问题。要是每次看到FTP(或SFTP)自动化,我的心都不会沉下去就好了;我一直在想“一定有更好的办法”。但这不是你的错,只是一次又一次地丢失了太多信息的不可避免的结果…
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
        }
    }        

}