【问题标题】:how download latest file from SFTP ( connection use key file and password ) using bash如何使用 bash 从 SFTP 下载最新文件(连接使用密钥文件和密码)
【发布时间】:2020-04-03 13:01:05
【问题描述】:

我的主要问题是我无法从 sftp 下载最新文件。 另外,我只有下载文件的权限。 文件名示例:transaction_20200403060011_5e86xxxxxx.08595559.csv。 下载所有文件:

   #!/usr/bin/expect
    spawn sftp -i /home/ubuntu/sc_sftp.txt xxx@xxx.com 
    expect "password:"
    send "xxx\n" 
    expect "sftp>"
    send "get *.csv\n"
    expect "sftp>"
    send "exit\n"
    interact

我只需要最新的文件,所以我尝试将文件名保存到 .txt 文件并读取我需要的文件名。它适用于 bash 命令。不幸的是,由于我使用 spawn 和 sftp 命令,我无法加载文件名。我的脚本,这不起作用:

#!/usr/bin/expect
spawn sftp -i /home/ubuntu/sc_sftp.txt xxx@xxx.com 
expect "password:"
send "xxx\n" 
expect "sftp>"
log_file -noappend RemoteFileList.txt
send "ls -1t\n"
expect "sftp>"
log_file
send "!sed -i '' '/ls -1/d' ./RemoteFileList.txt\n"
expect "sftp>"
send "!sed -i '' '/sftp>/d' ./RemoteFileList.txt\n"
expect "sftp>"
send "bye\n"
interact
set $file `(head -2 RemoteFileList.txt | tail -1)`
spawn sftp -i /home/ubuntu/sc_sftp.txt xxx@xxx.com 
expect "password:"
send "xxx\n" 
expect "sftp>"
send "get $file\n"
interact  

和错误:

can't read "file": no such variable
    while executing
"set $file `(head -2 RemoteFileList.txt | tail -1)`"
    (file "./s.sh" line 16)

当我添加了这些命令时:

send "ls -1t\n"
expect -re "(.+)\r\nsftp>"
send " $expect_out(0,string)"
expect "sftp>"
send "exit\n"
interact

我有:

sftp> ls -1t
file1.csv
file2.csv
file3.csv
sftp>   ls -1t
file1.csv
file2.csv
file3.csv
sftp>
sftp> file1.csv
Invalid command.
sftp>
sftp> file2.csv
sftp>
sftp> file3.csv
sftp>
sftp> sftp>exit
Invalid command.

有人可以帮我解决这个问题吗?

【问题讨论】:

  • Tcl 也是一种通用编程语言。您可以将它用于所有字符串操作。

标签: sftp expect


【解决方案1】:

这是 expect 比较乏味的方面之一。你会做这样的事情:

send "ls -1t\n"
expect -re "(.+)\r\nsftp>"

现在这些括号的内容(将是命令“ls -1t”,后面是实际结果)存储在数组变量$expect_out(1,string) 中——逗号周围没有空格。

预计使用\r\n 换行。

如果您在解析结果时需要帮助,请在此处发布。


之后

send "ls -1t\n"
expect -re "(.+)\r\nsftp>"

$expect_out(0,string) 包含

ls -1t\r\nfile1.csv\r\nfile2.csv\r\nfile3.csv\r\nsftp>

$expect_out(1,string) 包含

ls -1t\r\nfile1.csv\r\nfile2.csv\r\nfile3.csv

当你做send " $expect_out(0,string)"

sftp>  ls -1t
file1.csv
file2.csv
file3.csv
sftp>
sftp> file1.csv
Invalid command.
sftp>
sftp> file2.csv
sftp>
sftp> file3.csv
sftp>
sftp> sftp>exit
Invalid command.

您可以再次看到ls 命令。
然后您会看到“无效命令”错误 对于 file1.csv 试图作为命令执行。我很惊讶你 也不要将“file2.csv”和“file3.csv”的错误显示为命令。

您收到“无效命令”退出,因为您实际上发送了sftp> exit\n。 “sftp>”部分是 $expect_out(0,string) 的结尾——你没有 发送时“按回车键”。

要获取最新文件,您需要ls -1t 命令的第一行输出:

send "ls -1t\r"
expect -re "(.+)\r\nsftp>"

set lines [split $expect_out(1,string) "\n"]
set first_file [lindex $lines 1]
set first_file [string trimright $first_file "\r"]

set timeout -1
send "get $first_file\r"
expect "sftp>"
send "exit\r"
expect eof

【讨论】:

  • 感谢您的回答,但我仍然无法解析文件名。我尝试过类似 get $expect_out(1,string) 的方法,但它不起作用。我想我错过了什么。我将不胜感激
  • $expect_out(1,string)的内容是什么?
  • 我认为我在 sftp 上拥有的所有 3 个文件的名称,我已经在帖子中添加了内容。
猜你喜欢
  • 2018-01-24
  • 1970-01-01
  • 2016-11-23
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 2020-12-22
  • 1970-01-01
  • 2016-10-11
相关资源
最近更新 更多