如何使用expect从SFTP服务器捕获sftp ls命令的输出?

时间:2017-03-17 11:50:06

标签: linux bash sftp expect

自从过去三天以来,我一直在努力编写一个bash脚本,该脚本可以自动从SFTP服务器下载文件。我已经构建了程序的结构,已经在片段中进行了测试,但这就是我所坚持的。

我登录SFTP服务器:

/usr/bin/expect <<EOD
spawn sftp $ftp_server
expect "password:"
send "$password\r"
expect "sftp>"
send "ls\r"
expect "sftp>\r"
send "exit\r"
EOD

我想循环ls命令的输出来决定下载哪个文件。我尝试将输出重定向到文本文件,然后从那里获取文件名,但它存储了“sftp&gt;”提示和其他不相关的信息。如何存储ls的干净expect输出并在其上循环?

2 个答案:

答案 0 :(得分:2)

使用-b开关传递带有命令(ls)的脚本,而不是在标准输入中提供它们。

这样sftp将以批处理模式运行而不会出现提示。

答案 1 :(得分:0)

有一个示例如何捕获所有要列出的文件名:

#!/bin/sh
# the next line restarts using expect \
    LC_TYPE=C exec expect -f "$0" -- "$@"

# do not show sftp output by default 
log_user 0

set ftp_server 127.0.0.1
set password pass
set sftp_prompt {sftp> }

spawn -noecho sftp $ftp_server

expect "password:"
send "$password\r"

expect $sftp_prompt

# 'ls -1' will show filenames line by line
send "ls -1\r"

# ignore echo of command from sftp
expect -re {ls -1\r?\n}

# init empty list for filename collecting
set files {}

expect -re {([^\r\n]+)\r?\n} {
    # catch each filename line by line and put it to list 'files'
    lappend files $expect_out(1,string)

    # run current 'expect' again to catch next filename
    exp_continue
} -ex $sftp_prompt {
    # catch sftp prompt to break
}

# loop over example :)
foreach f $files {
    puts $f
}