Pular para o conteúdo principal
Em meu último blog eu falei sobre a automatização da transferência de arquivos usando FTP. Há três problemas com o uso do FTP. Primeiro, sua senha é enviada através da rede em texto claro, tornando-a disponível a qualquer pessoa com um analisador de protocolo. Segundo, seus dados também são enviados em texto claro. Terceiro, você tem que registrar sua senha em algum lugar no módulo, seja na macro ou no arquivo .netrc. Devido a estas questões, muitos sites mandataram ou estão pensando em mandar que o SFTP, o subsistema seguro de FTP do SSH, seja usado no lugar do FTP. Entretanto, você não pode simplesmente substituir ftp por sftp em sua macro de comando (figura 1) e esperar que ele funcione (figura 2).

 

&attach_input
sftp 172.16.1.116
nd
MYPASSWORD
put foo
&if (command_status) ^= 226 &then &goto ERROR1
get bar
&if (command_status) ^= 226 &then &goto ERROR2
quit
&
&label ERROR1
..display_line Could not put file
quit
&return
&
&label ERROR2
..display_line Could not get file
quit
&return

Figura 1 - sftp1.cm - substituindo o comando ftp por sftp em uma macro de comando

 

sftp1
Connecting to 172.16.1.116...
dup2: Bad file number.
Error on line 3 of sftp1.
command_processor: Object not found. nd. In command macro
%phx_vos#m15_mas>SysAdmin>Noah_Davids>sftp1.cm
ready  12:39:59

 

Figura 2 - sftp1.cm de funcionamento
O problema é uma incompatibilidade entre a forma como os comandos VOS nativos e o código aberto POSIX tratam a entrada. Entretanto, o SFTP, como o FTP, permite criar um arquivo com uma lista de solicitações (figura 3), que será executado automaticamente (figura 4).

 


put foo
get bar

 

Figura 3 - sftp2.input - arquivo contendo os pedidos de sftp a executar

 


sftp -b sftp2_input nd@172.16.1.116
nd@172.16.1.116's password:
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/foo
sftp> get bar
Couldn't stat remote file: No such file or directory
File "/SysAdmin/Noah_Davids/bar" not found.
Ready  13:06:45

 

Figura 4 - execução com um arquivo de entrada de solicitações e um prompt de senha
Você notará na figura 4 que o sftp está solicitando uma senha. Não há maneira de colocar a senha no arquivo de entrada. A ÚNICA maneira de contornar a solicitação de senha é usar a autenticação de chave pública (figura 5).

 

sftp -b sftp2_input nd@172.16.1.116
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/foo
sftp> get bar
Couldn't stat remote file: No such file or directory
File "/SysAdmin/Noah_Davids/bar" not found.
Ready  13:12:28

 

Figura 5 - execução com um arquivo de entrada de solicitações, usando autenticação de chave pública para eliminar a solicitação de senha

 

Você pode encontrar um artigo sobre como criar uma autenticação de chave pública aqui - http://members.cox.net/ndav1/self_published/publickey_authentication_setup.html

Infelizmente, a sftp executará todos os pedidos no arquivo de entrada um após o outro, não há mecanismo para testar se a transferência funcionou ou não.

Como as macros de comando não podem ser usadas, existem alternativas? O produto gnu_tools é enviado com um programa chamado expect. Ele pode ser usado para enviar comandos, esperar por qualquer número de respostas diferentes e fazer algo baseado no que ele vê no fluxo de saída. Não sou especialista em esperar, mas o script da figura 6 ajudará você a começar. Se você procurar na web por "esperar scripts", você encontrará muitas referências que o ajudarão a personalizar meu exemplo simples.

 

# If we get an end-of-file (eof) it means that the sftp process
# terminated. Report the last command that was sent.
#
proc goteof {cmd} {
puts "sftp connection unexpectedly closed n"
puts "last text received wasn"
puts "<<"
puts $cmd
puts ">>nnn"
exit
}
# Este procedimento combina com a expressão regular de procura de cordões-chave
# na saída coletada do comando que foi executado. Neste caso, o
# Estou apenas relatando o tipo de erro, mas outras coisas podem ser feitas
# também. Eu também verifico apenas 2 erros. Existem outros. Você terá
# para adicioná-los conforme você os encontrar.
#
proc proc proc procerrors {buf cmd} {
se [regexp {.*não foi encontrado] $buf] {
coloca "$cmd FAILED : não encontradonnn"
retorno 1
}
se [regexp {.*Permissao negada} $buf] {
coloca "$cmd FAILED : problemas de acessonnn".
retorno 1
}
retornar 0
}# definir o tempo limite para -1 para que não haja tempo limite. O tempo limite padrão é de 10 segundos
# e a maioria das transferências de arquivos demora mais do que isso. Eu decidi não
# tempo esgotado, você pode mudar isso.
tempo limite -1

# start sftp
spawn sftp nd@172.16.1.116

# esperar pelo prompt de roubo, mas se tivermos um prompt de autenticação, terminando em
# sim/não informar um problema de segurança e saída.
esperar {
"sim/não?" { coloca
"nnnConectamo-nos ao servidor errado ou o servidor foi recarregado".
coloca
"A chave do servidor deve ser validada antes que este script possa ser executado novamente.nnn".
saída }
sftp>
}

# mudar para um diretório conviente para testes
enviar "cd sftp_testr"
esperar {
eof { goteof "cd sftp_test" }
sftp>
}

# chamar a verificação de erros passando todos os caracteres coletados para cima do
# sftp> pronto. Também o comando que foi enviado para sftp. Se o
# procedimento checkforerrors devolve 1 saída do roteiro. Novamente, você pode
# fazer outras coisas.
if {[checkforerrors $expect_out(buffer) "cd sftp_test"] == 1} {saída }

enviar "put foor"
esperar {
eof { goteof "put foo" }
sftp>
}
if {[checkforerrors $expect_out(buffer) "put foo"] == 1} {saída }

enviar "get barr
esperar {
eof { goteof "get bar" }
sftp>
}
if {[checkforerrors $expect_out(buffer) "get bar"] == 1} {saída }

enviar "quitr
esperar eof
coloca "script donenn"

 

Figura 6 - sftp3.exp - esperar script para automatizar o SFTP

 

expect sftp3.exp
spawn sftp nd@172.16.1.116
Connecting to 172.16.1.116...
The authenticity of host 172.16.1.116(172.16.1.116)' can't be established
+.
RSA key fingerprint is 37:f4:1a:56:64:af:ab:8a:7c:0b:36:47:c5:6c:1d:1a.
Are you sure you want to continue connecting (yes/no)?
Nós nos conectamos ao servidor errado ou o servidor foi recarregado.
A chave do servidor deve ser validada antes que este script possa ser executado novamente.pronto 10:41:10

 

Figura 7 - execução de sftp3.exp expect script com aviso de segurança

 

expect sftp3.exp
spawn sftp nd@172.16.1.116
Connecting to 172.16.1.116...
sftp> cd sftp_test
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/sftp_test/foo
sftp> get bar
Não foi possível estabelecer um arquivo remoto: Nenhum arquivo ou diretório deste tipo
Arquivo "/SysAdmin/Noah_Davids/sftp_test/bar" não encontrado.
sftp> get bar FAILED : not foundready 10:42:11

 

Figura 8 - execução do sftp3.exp espera script sem aviso, mas com uma transferência falhada

Finalmente, em meu blog FTP mencionei que o FTP era capaz de ler arquivos que ainda estavam abertos e isto, em algumas ocasiões, resultou na transferência de arquivos incompletos, sugeri que se a macro FTP espera que um arquivo apareça em um local e depois o transfere, a macro deve verificar para ter certeza de que não está mais bloqueado. O mesmo problema pode ocorrer com o SFTP e a solução é a mesma. Você pode colocar a verificação de bloqueio de arquivo em uma macro de comando (figura 9) e então, quando o arquivo não estiver mais bloqueado, esperar a chamada com o script apropriado.

&label AGAIN
&if (exists new_file) = 1 & (locked new_file) = 0 &then &goto EXPECT
display_line new_file not ready for transfer as of (time)
sleep -seconds 15
&goto AGAIN
&
&
&label EXPECT
expect sftp3.exp

 

Figura 9 - teste de macro de comando para bloqueio de arquivo antes da chamada esperar

© 2020 Stratus Technologies.