如何使用 bash 从 SFTP 下载最新文件(连接使用密钥文件和密码)
how download latest file from SFTP ( connection use key file and password ) using bash
我的主要问题是我无法从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 文件并读取我 need.It 使用 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.
谁能帮我解决这个问题?
这是 expect 比较乏味的方面之一。你会做这样的事情:
send "ls -1t\n"
expect -re "(.+)\r\nsftp>"
现在这些括号的内容(将是命令 "ls -1t" 后跟实际结果)存储在数组变量 $expect_out(1,string)
中 -- 逗号周围没有空格。
预计使用 \r\n
换行。
如果您在解析结果时需要帮助,post 此处。
之后
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
命令了
然后你看到 "invalid command" 错误
for file1.csv
试图作为命令执行。我很惊讶你
也不要将 "file2.csv" 和 "file3.csv" 的错误显示为命令。
你得到 "invalid command" 退出,因为你实际上已经发送了 sftp> exit\n
。
"sftp> " 部分是 $expect_out(0,string) 的末尾——你没有
"hit enter" 你发送的时候。
要获取最新文件,您需要 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
我的主要问题是我无法从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 文件并读取我 need.It 使用 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.
谁能帮我解决这个问题?
这是 expect 比较乏味的方面之一。你会做这样的事情:
send "ls -1t\n"
expect -re "(.+)\r\nsftp>"
现在这些括号的内容(将是命令 "ls -1t" 后跟实际结果)存储在数组变量 $expect_out(1,string)
中 -- 逗号周围没有空格。
预计使用 \r\n
换行。
如果您在解析结果时需要帮助,post 此处。
之后
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
命令了
然后你看到 "invalid command" 错误
for file1.csv
试图作为命令执行。我很惊讶你
也不要将 "file2.csv" 和 "file3.csv" 的错误显示为命令。
你得到 "invalid command" 退出,因为你实际上已经发送了 sftp> exit\n
。
"sftp> " 部分是 $expect_out(0,string) 的末尾——你没有
"hit enter" 你发送的时候。
要获取最新文件,您需要 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