在 Expect for SFTP 中创建外部命令集

发布于 2024-12-14 09:12:52 字数 1294 浏览 5 评论 0原文

目前我有一些代码通过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 语句中所需的循环。希望有人能知道如何实现这一目标。

Currently I have some code that is doing an SFTP via expect/tcl. Its something like this:

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
    }
}

Occasionally I run into situations where an FTP server has return codes or messages that do not match what is already populated in the code base. Instead of modifying the core code for these what I would like to do is have an external file (ex: returncodes.tbl) where I can have a list of messages like:

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

So then it will interpret it in the expect code like:

-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 know how to read the external file and chop the variables up (open/read/split). However I cannot figure out how to create the loop needed within the expect statement. Was hoping someone might have an idea on how to accomplish this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝不服输 2024-12-21 09:12:52

我想我会通过在现有的 Expect 语句末尾构建一个案例来解决这个问题,该案例可以捕获模式并使用正则表达式对其进行解析。然后您只需要一个 for 循环来清除文件并获取匹配项。

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

(我不知道你是如何加载文件的,所以现在我假设它是一个由“\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
        }
    }        

}

I think I would approach this, by building a case on the end of your existing expect statement that can catch a pattern and parse it with a regexp. Then you just need a for loop to weed through the file and snag a match.

You may need to play with the regexp to get it to work just right - sending \r a second time will align the expect buffer so that you can catch the error code.

(I don't know how you loaded the file, so right now I'm assuming it's a flat list split by "\n" and ";")

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
        }
    }        

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文