Pergunta

Eu estou tentando executar um comando interativo através paramiko. As tentativas de execução de cmd para solicitar uma senha, mas eu não sei como fornecer a senha através exec_command de paramiko e os trava de execução. Existe uma maneira de enviar valores para o terminal se uma execução cmd espera de entrada interativa?

ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")

Alguém sabe como isso pode abordadas? Obrigado.

Foi útil?

Solução

Os paramiko navios distribuição completa com um monte de bom demos .

No subdiretório demos, demo.py e interactive.py temos exemplos TTY interativos completos que provavelmente seria um exagero para a sua situação.

No seu exemplo acima ssh_stdin age como um objeto de arquivo padrão do Python, então ssh_stdin.write deve funcionar, desde que o canal ainda está aberto.

Eu nunca precisei escrever para stdin, mas os docs sugerem que um canal é fechada assim como um comando saídas, portanto, usando o método stdin.write padrão para enviar uma senha-se, provavelmente, não vai funcionar. Existem comandos nível paramiko mais baixos no próprio canal que lhe dão mais controle - ver como o SSHClient.exec_command método é implementado para todos os detalhes.

Outras dicas

Eu tive o mesmo problema ao tentar fazer uma sessão SSH interativo usando ssh , um garfo de paramiko.

Eu cavei ao redor e encontrei este artigo:

link Atualizado (última versão antes do link gerado a 404): http://web.archive.org/web/20170912043432/http://jessenoller.com/2009/ 05/02 / ssh-programming-com-paramiko-completamente-diferente /

Para continuar o seu exemplo, você poderia fazer

ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")
ssh_stdin.write('password\n')
ssh_stdin.flush()
output = ssh_stdout.read()

O artigo vai mais em profundidade, descrevendo um shell totalmente interativo em torno exec_command. Achei isso muito mais fácil de usar do que os exemplos a fonte.

link Original : http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

Você precisa Pexpect para obter o melhor dos dois mundos (esperar e invólucros ssh).

Eu não estou familiarizado com paramiko, mas isso pode funcionar:

ssh_stdin.write('input value')
ssh_stdin.flush()

Para obter informações sobre stdin:

http://docs.python.org/library /sys.html?highlight=stdin#sys.stdin

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server_IP,22,username, password)


stdin, stdout, stderr = ssh.exec_command('/Users/lteue/Downloads/uecontrol-CXC_173_6456-R32A01/uecontrol.sh -host localhost ')
alldata = ""
while not stdout.channel.exit_status_ready():
   solo_line = ""        
   # Print stdout data when available
   if stdout.channel.recv_ready():
      # Retrieve the first 1024 bytes
      solo_line = stdout.channel.recv(1024) 
      alldata += solo_line
   if(cmp(solo_line,'uec> ') ==0 ):    #Change Conditionals to your code here  
     if num_of_input == 0 :
      data_buffer = ""    
      for cmd in commandList :
       #print cmd
       stdin.channel.send(cmd)        # send input commmand 1
      num_of_input += 1
     if num_of_input == 1 :
      stdin.channel.send('q \n')      # send input commmand 2 , in my code is exit the interactive session, the connect will close.
      num_of_input += 1 
print alldata
ssh.close()              

Por que a stdout.read () irá travar se o uso dierectly sem verificar stdout.channel.recv_ready (): em enquanto stdout.channel.exit_status_ready ():

Para o meu caso, depois de comando executado no servidor remoto, a sessão está aguardando entrada do usuário, após a entrada de 'q', que vai fechar a conexão. Mas antes de introduzir 'q', o stdout.read () irá esperar por EOF, parece que este methord não funciona se tampão é maior.

  • Eu tentei stdout.read (1) no tempo, ele funciona
    Tentei stdout.readline () no tempo, ele funciona também.
    stdin, stdout, stderr = ssh.exec_command ( '/ Users / lteue / downloads / uecontrol')
    stdout.read () irá travar

Dê uma olhada exemplo e fazer em forma similar

(sorce de http: // jessenoller. cOM / 2009/02/05 / ssh-programming-with-paramiko-completamente-diferente / ):

    ssh.connect('127.0.0.1', username='jesse', 
        password='lol')
    stdin, stdout, stderr = ssh.exec_command(
        "sudo dmesg")
    stdin.write('lol\n')
    stdin.flush()
    data = stdout.read.splitlines()
    for line in data:
        if line.split(':')[0] == 'AirPort':
            print line

Você pode usar esse método para enviar qualquer mensagem de confirmação que você quer como "OK" ou a senha. Esta é a minha solução com um exemplo:

def SpecialConfirmation(command, message, reply):
    net_connect.config_mode()    # To enter config mode
    net_connect.remote_conn.sendall(str(command)+'\n' )
    time.sleep(3)
    output = net_connect.remote_conn.recv(65535).decode('utf-8')
    ReplyAppend=''
    if str(message) in output:
        for i in range(0,(len(reply))):
            ReplyAppend+=str(reply[i])+'\n'
        net_connect.remote_conn.sendall(ReplyAppend)
        output = net_connect.remote_conn.recv(65535).decode('utf-8') 
    print (output)
    return output

CryptoPkiEnroll=['','','no','no','yes']

output=SpecialConfirmation ('crypto pki enroll TCA','Password' , CryptoPkiEnroll )
print (output)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top