'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.
Solution 1:[1]
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()
Solution 2:[2]
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.
Solution 3:[3]
cat is reading from stdin. Use echo instead.
'echo ' + localstring + ' > newfile.txt'
If you need to echo multiple lines, use -e flag:
echo -e "Line1\nLine2\n" > file.txt
Solution 4:[4]
Just an alternative and easy way. Not necessarily the best one.
I had a complex code in hand and didn't want to rewrite the SSH module with SCP stuff... so I did the following
file_path = ""
file_content = "" # Can be multi - line
command = f"""
cat << EOL > {file_path}
{file_content}
EOL
"""
stdin, stdout, stderr = client.exec_command(command)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nigel |
| Solution 2 | |
| Solution 3 | kirelagin |
| Solution 4 | Jay Joshi |
