python - invoke_shell - Ejecución de comandos interactivos en Paramiko
python ssh paramiko tutorial (6)
Echa un vistazo al ejemplo y hazlo de manera similar
(sorce de http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/ ):
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
Estoy tratando de ejecutar un comando interactivo a través de paramiko. La ejecución de cmd intenta solicitar una contraseña, pero no sé cómo proporcionar la contraseña a través del exec_command de paramiko y se cuelga la ejecución. ¿Hay alguna manera de enviar valores al terminal si una ejecución de cmd espera la entrada de forma interactiva?
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")
¿Alguien sabe cómo se puede abordar esto? Gracias.
La distribución completa de paramiko viene con muchas buenas demos .
En el subdirectorio de demos, demo.py
e interactive.py
tienen ejemplos de TTY interactivos completos que probablemente sean excesivos para su situación.
En su ejemplo anterior, ssh_stdin
actúa como un objeto de archivo Python estándar, por lo que ssh_stdin.write
debería funcionar siempre que el canal aún esté abierto.
Nunca he necesitado escribir en stdin, pero los documentos sugieren que un canal se cierra tan pronto como sale un comando, por lo que usar el método estándar stdin.write
para enviar una contraseña probablemente no funcionará. Hay comandos paramiko de nivel inferior en el canal mismo que le dan más control: vea cómo se implementa el método SSHClient.exec_command
para todos los detalles sangrientos.
Necesitas que Pexpect obtenga lo mejor de ambos mundos (contenedores de espera y de ssh).
No estoy familiarizado con paramiko, pero esto puede funcionar:
ssh_stdin.write(''input value'')
ssh_stdin.flush()
Para obtener información sobre stdin:
http://docs.python.org/library/sys.html?highlight=stdin#sys.stdin
Tuve el mismo problema al intentar hacer una sesión ssh interactiva usando ssh , un tenedor de Paramiko.
Busqué y encontré este artículo:
http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/
Para continuar tu ejemplo, podrías hacer
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()
El artículo va más en profundidad, describiendo un shell completamente interactivo en exec_command. Encontré esto mucho más fácil de usar que los ejemplos en la fuente.
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 qué stdout.read () se bloqueará si se usa directamente sin verificar stdout.channel.recv_ready (): en while stdout.channel.exit_status_ready ():
Para mi caso, después de ejecutar el comando en el servidor remoto, la sesión está esperando la entrada del usuario, después de la entrada ''q'', cerrará la conexión. Pero antes de ingresar ''q'', stdout.read () esperará EOF, parece que este método no funciona si el buffer es más grande.
- Intenté stdout.read (1) en while, funciona
Intenté stdout.readline () en while, también funciona.
stdin, stdout, stderr = ssh.exec_command (''/ Users / lteue / Downloads / uecontrol'')
stdout.read () se bloqueará