Как загрузить последний файл из SFTP (соединение использовать файл ключа и пароль), используя bash - PullRequest
0 голосов
/ 03 апреля 2020

Моя главная проблема в том, что я не могу загрузить последний файл из sftp. Также у меня есть разрешение только на скачивание файла. Пример имени файла :action_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.

Может ли кто-нибудь помочь мне с этим?

1 Ответ

1 голос
/ 03 апреля 2020

Это один из самых утомительных аспектов ожидания. Вы сделаете что-то вроде этого:

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

Теперь содержимое этих скобок (это будет команда "ls -1t", за которой следуют фактические результаты) сохраняется в переменной массива $expect_out(1,string) - - без пробелов вокруг запятой.

ожидайте использования \r\n для разрывов строк.

Если вам нужна помощь в разборе результатов, напишите здесь.


После

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

$ Ожидаемый-0 (0, строка) содержит

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

$ Ожидаемый-1 (1, строка) содержит

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>» была конечной частью $ Ожидаем (0, строка) - вы не «нажали ввод», когда отправили это.

Чтобы получить самый последний файл, вам нужна первая строка вывода команды 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
...