Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write a local string to a remote file using python paramiko

I need to write a string to a file on a remote host using python's paramiko module. I've been trialing various methods of redirecting input but with no success.

The localstring in the below code snippet is populated with the result of a cat command

stdin, stdout, stderr = hydra.exec_command('cat /file.txt')
localstring = stdout.read()
manipulate(localstring)
hydra.exec_command('cat > newfile.txt\n' + localstring + '\n')

I seem to have my script hang or receive an EOF error or not have the resulting string appear in the file at all. Note that the file has multiple lines.

like image 887
user2451085 Avatar asked Jun 04 '13 09:06

user2451085


People also ask

How do I connect to a Paramiko remote server?

A Paramiko SSH Example: Connect to Your Server Using a Password. This section shows you how to authenticate to a remote server with a username and password. To begin, create a new file named first_experiment.py and add the contents of the example file. Ensure that you update the file with your own Linode's details.

What is Paramiko SSHClient ()?

SSHClient. A high-level representation of a session with an SSH server. This class wraps Transport , Channel , and SFTPClient to take care of most aspects of authenticating and opening channels. A typical use case is: client = SSHClient() client.

Does Paramiko work on FTP?

Paramiko is an SFTP library, not FTP library. SFTP servers that do not require any credentials are almost non-existent. And even the error message you are getting suggests that you are not connecting to an SFTP server. If it is indeed an FTP server, you need to use an FTP library, like ftplib.


2 Answers

You could also use the ftp capability:

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('example.com', username='username', password='password')

ftp = ssh.open_sftp()
file=ftp.file('remote file name', "a", -1)
file.write('Hello World!\n')
file.flush()
ftp.close()
ssh.close()
like image 96
Nigel Avatar answered Sep 21 '22 07:09

Nigel


As a variation of @Nigel's answer, you can use putfo, which (by default) additionally verifies the file's size after writing and makes sure the file is properly closed.

import paramiko
from io import BytesIO

ssh = paramiko.SSHClient()
ssh.connect(…)

ftp = ssh.open_sftp()
ftp.putfo(BytesIO(localstring.encode()), 'newfile.txt')

ftp.close()
ssh.close()

[Edit] Do not use StringIO as it reports the number of characters as length, while paramiko uses stat to report the number of bytes of the file on the remote system. If they mismatch, the transfer fails.

like image 39
Caesar Avatar answered Sep 21 '22 07:09

Caesar