【问题标题】:Expect Script for SFTP not working in bash期望 SFTP 的脚本在 bash 中不起作用
【发布时间】:2020-07-01 12:46:45
【问题描述】:

我创建了一个 shell 脚本,其中包含一个用于从远程位置获取文件的期望脚本。一切正常,直到发送一些命令。无论是 'ls' 或 'pwd' 还是任何其他命令,expect 脚本都会突然结束。你能帮我解决这个问题吗?

注意:安全不是问题,因此不使用公钥。

#!/bin/ksh

FTPREMOTEPATH=/Inbox
FTPREMOTEFILENAME=test.CSV


/usr/bin/expect -f - <<EOFEXPECT1
set timeout 60
spawn sftp -oPort=1002 username@test.server.com
expect {
        default { exit 1}
        -re "failed|invalid password|Permission denied" {exit 2}
        "Connection closed" {exit 1}
        timeout {exit 1}
}

expect "Password:"
send "password\r"

expect {
        default {exit 1}
        -re "password|Enter password for " {puts "Incorrect Password"; exit 2}
        "sftp>" {send "cd $FTPREMOTEPATH \r"}
}

expect "sftp>"
send "pwd\r"

send "get $FTPREMOTEFILENAME \r";

EOFEXPECT1

在上面的脚本中,脚本在发送 cd $FTPREMOTEPATH 后突然结束。

下面是输出:

$ ./test.sh
spawn sftp -oPort=1002 username@test.server.com
Enter password for username
Password:
sftp> cd /Inbox
sftp> $

【问题讨论】:

  • 如果你想看到更多的输出,你需要添加更多的expect 行。通常一个脚本只是发送...期望...发送...期望。最后使用expect eof 等待连接关闭(如果您发送了应该关闭连接的命令)。
  • 看看sexpect (Expect for Shells),您可以使用它来编写仅使用shell代码Expect脚本。

标签: linux shell ftp sftp expect


【解决方案1】:

原因是您的 Expect 脚本已到达脚本末尾,因此在 ftp 进程有机会完成文件下载之前终止子 (ftp) 进程。

【讨论】:

    【解决方案2】:

    想象一下,你打电话给当地的一家餐馆,说“给我弄点吃的”然后就挂断了。餐厅应该做什么?

    当您等待 sftp 提示时,您正在等待送餐。

    我推荐两件事:

    1. send "get ... 之前将超时值更改为 -1 -- 如果接收文件的时间超过 60 秒,这将有所帮助。
    2. 在您发送“再见”之后,expect eof -- 让 sftp 连接正常关闭。

    【讨论】:

    • 谢谢@glenn,这帮助我获得了洞察力。这是否意味着,一旦被告知期望 GET 文件,它就无事可做,所以它会停止并杀死 SFTP ?因此需要一个“再见”声明?
    • 如果get 是脚本的最后一行,则指示 sftp 开始下载,但随后脚本结束。当脚本结束时,生成的 sftp 进程立即被杀死。
    【解决方案3】:

    好的,显然我在 EOF (EOFEXPECT1) 之前错过了 expect "sftp>" {send "bye\n"}

    但是,我仍然有兴趣了解 bye 在期望脚本中的重要性。

    这是更新后的工作代码:

    #!/bin/ksh
    
    FTPREMOTEPATH=/Inbox
    FTPREMOTEFILENAME=test.CSV
    
    
    /usr/bin/expect -f - <<EOFEXPECT1
    set timeout 60
    spawn sftp -oPort=1002 username@test.server.com
    expect {
            default { exit 1}
            -re "failed|invalid password|Permission denied" {exit 2}
            "Connection closed" {exit 1}
            timeout {exit 1}
    }
    
    expect "Password:"
    send "password\r"
    
    expect {
            default {exit 1}
            -re "password|Enter password for " {puts "Incorrect Password"; exit 2}
            "sftp>" {send "cd $FTPREMOTEPATH \r"}
    }
    
    expect "sftp>"
    send "pwd\r"
    
    send "get $FTPREMOTEFILENAME \r";
    
    expect "sftp>" {send "bye\n"}
    
    EOFEXPECT1
    

    【讨论】:

    • 脚本的最后一行,在你发送bye之后,应该是expect eof
    • @glennjackman - “eof”可以省略,因为不需要任何操作(即一个简单的“expect”(没有 eof)就足够了)。
    猜你喜欢
    • 2016-10-01
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 2022-01-21
    • 2014-08-11
    • 1970-01-01
    相关资源
    最近更新 更多