Question

I'm trying to use Paramiko to connect to a remote host and execute a number of text file substitutions.

i, o, e = client.exec_command("perl -p -i -e 's/" + initial + "/" 
                              + replaced + "/g'" + conf);

Some of these commands need to be run as sudo, which results in:

sudo: sorry, you must have a tty to run sudo

I can force pseudo-tty allocation with the -t switch and ssh.

Is it possible to do the same thing using paramiko?

Was it helpful?

Solution

I think you want the invoke_shell method of the SSHClient object (I'd love to give a URL but the paramiko docs at lag.net are frame-heavy and just won't show me a specific URL for a given spot in the docs) -- it gives you a Channel, on which you can do exec_command and the like, but does that through a pseudo-terminal (complete with terminal type and numbers of rows and columns!-) which seems to be what you're asking for.

OTHER TIPS

Actually it's quite simple. Just:

stdin, stdout, stderr = client.exec_command(command,  get_pty=True)

The following code works for me:

#!/usr/bin/env python
import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('localhost',username='root',password='secret')
chan = ssh.get_transport().open_session()
chan.get_pty()
chan.exec_command('tty')
print(chan.recv(1024))

This was just assembled from looking at a few examples online... not sure if its the "right" way.

According to the sudo manpage:

The -S (stdin) option causes sudo to read the password from the standard input instead of the terminal device. The password must be followed by a newline character.

You can write to the stdin because it is a file object with write():

import paramiko

client = paramiko.client.SSHClient()
client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
client.connect(hostname='localhost', port=22, username='user', password='password')
stdin, stdout, stderr = client.exec_command('sudo -S aptitude update')
stdin.write('password\n')
stdin.flush()
# print the results
print stdout.read()
client.close()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top