Sudo Python code to connect to remote server but I am not getting any output. I am able to connect to remote using pexpect but on windows it does not work.
from subprocess import Popen,PIPE
command = "plink.exe -ssh test#test.com -pw root123"
sh = Popen(command, stdin=PIPE, stdout=PIPE)
sh.stdin.write('ls /\n')
sh.stdin.write('ls /usr\n')
sh.stdin.close()
out = sh.stdout.read()
Related
I want to run a program on a remote server and send command to it from my computer using subprocess and Paramiko. Is below can be usefull?
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('host', username='user', password="password")
myprogramme = subprocess.Popen("myprogramme.exe", stdin=subprocess.PIPE)
myprogramme.stdin.write(ssh_stdout.read())
myprogramme.communicate("some_inputs\n")
myprogramme.kill
You cannot run a program on a remote server over SSH with subprocess.
Use SSHClient.exec_command to execute your command.
Then you can feed your command to the process using the returned stdin:
Pass input/variables to command/script over SSH using Python Paramiko
I have to write a python script that logs on using ssh to a remote server and access the Cassandra database there . I am using paramiko but after login in to the server , it doesn't connect to Cassandra and script hangs .
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('10.65.XXX.XX', username='sinha.aman', password='', key_filename='/root/.ssh/id_rsa.pub')
stdin, stdout, stderr = ssh.exec_command('cqlsh 10.65.XXX.XX 9042 -u ABC123 -p 12345')
stdin, stdout, stderr = ssh.exec_command('ls')
print(stdout.readlines())
ssh.close()
Maybe the script waits from some user input since you're opening a cqlsh session?
Try adding the -e flag to cqlsh command:
cqlsh -e 'select * from test.emp'
Change accordingly to your script.
Check also cqlsh --help for -e flag.
-e EXECUTE, --execute=EXECUTE
Execute the statement and quit.
stdin, stdout, stderr = ssh.exec_command('cqlsh 10.65.XXX.XX 9042 -u ABC123 -p 12345')
Here it is opening a cqlsh prompt, which is expecting a command to be executed, not returning any output.
Script is waiting for an input command. We have to pass cqlsh command to get the output.
By adding "-e help" or any other command will solve the issue.
stdin, stdout, stderr = ssh.exec_command('cqlsh 10.65.XXX.XX 9042 -u ABC123 -p 12345 **-e help** ')
For better understanding, execute the command manually in remote server, where you will see a cqlsh prompt waiting for command.
For all the cqlsh commands please refer
https://docs.datastax.com/en/cql-oss/3.x/cql/cql_reference/cqlshCommandsTOC.html
I am currently working on a script where when I launch an EC2 instance, I send a paramiko command to rename the host name. Because this is a custome AMI, I cannot use the AWS Boto3 CLI to do it, so I need to do it via an SSH command.
The problem I am running into, is Paramiko seems to fail at passing my specific command. It will pass other commands just fine, but I am assuming I am running into some sort of limitation of either paramiko or python and cannot seem to troubleshoot it. This is for a RHEL instance, so renaming the Network file is the only way I can think to do this.
If I run the command, as is, through the terminal of the host, it works. So something between paramiko and this command seems to be the blocker.
Here is my sample script t hat should work, but seems to fail at running the command.
#!/usr/bin/env python
import boto3
import time
import subprocess
import paramiko
import StringIO
c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
c.connect(hostname = '12.34.56.78', username = "username", key_filename='''/Users/mallachar/Downloads/testkey.pem''' )
stdin , stdout, stderr = c.exec_command('sudo sed -i -E "s/^HOSTNAME.*/HOSTNAME=testhost.company/" /etc/sysconfig/network')
print stdout.read()
print stderr.read()
c.close
Here is me printing stdout and stderr
sudo: sorry, you must have a tty to run sudo
Pretty simple, I had to add this to the command.
get_pty=True
so
stdin , stdout, stderr = c.exec_command('sudo sed -i -E "s/^HOSTNAME.*/HOSTNAME=testhost.company/" /etc/sysconfig/network',get_pty=True)
I am trying to execute few scripts in remote linux machine from windows host machine. I am hoping to achieve this using python subprocess +putty/plink.
When I try Putty or plink commands from windows cmd, it works fine. But if I try the same command using python subprocess, I get a lot of errors.
C:\Users\username>plink.exe username#machinename -pw password
Works fine. But when I try from python,
process = subprocess.Popen('plink.exe username#machinename -pw password'.split(),
env={'PATH':'C:\\Program Files (x86)\\PuTTY\\'},
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Throws the following error.
Unable to open connection:
gethostbyname: unknown error'
process = subprocess.Popen("putty.exe -ssh -2 -l username -pw password -m C:\\script.sh machinename",
env={'PATH':'C:\\Program Files (x86)\\PuTTY\\'},
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
,shell=True);
Unable to open connection:
gethostbyname: unknown error'
I tried subprocess.check_ouput too with no luck.
output = subprocess.check_output("putty.exe -ssh -2 -l username -pw password -m C:\\script.sh machinename", stderr=subprocess.STDOUT,shell=True)
Throws the following error
CalledProcessError: Command 'putty.exe -ssh -2 -l username -pw
password -m C:\script.sh machinename' returned non-zero exit status 1
Could this be a firewall issue?
I highly advise against using PuTT or in general every external program to connect to shh and then interface with pipes.
Using the python library paramiko this can be done much better.
For example:
# ... connect like one of the examples on github
stdin, stdout, stderr = client.exec_command('ls')
for line in stdout:
print '... ' + line.strip('\n')
I can execute a script from python environment locally using subprocess but due to cross platform issues, I have to execute it on a remote server and get back the results on my local machine.
The directory parserpath contains some third party modules that can be executed using a script run.sh present in parserpath directory. However this parserpath directory is present on a remote server.
This is what I have, but this will work only if parserpath is a local directory. How can I ssh to a remote directory and run the script run.sh?
def run_parser(filename):
current_dir = os.getcwd()
parser_path="/parserpath"
os.chdir(parser_path)
subprocess.call("./run.sh " + filename, shell=True)
os.chdir(current_dir)
With most linux shells, you can run a command in a different working directory by executing a subshell as in
/home/usr> (cd /usr/local/bin;pwd)
/usr/local/bin
/home/usr>
You can do the same thing through ssh to the remote system. Depending on which ssh client you use, you may thin that up a bit. For instance, with paramikos exec_command, a new remote shell is created for each command so cd /path/on/remote/machine;./run.sh is sufficient.
A minimalist example for paramiko on python 2.x is
import sys
import paramiko
try:
hostname, username, password, targetpath = sys.argv[1:5]
except ValueError:
print("Failed, call with hostname username password targetpath")
command = "cd {};pwd".format(targetpath)
print("Command to send: {}".format(command))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=hostname, username=username, password=password)
stdin, stdout, stderr = ssh.exec_command("cd {};pwd".format(targetpath))
print(stdout.read())
ssh.close()
python3 should be similar. There are other options like libssh2 bindings for python, pexpects ssh support and etc...
Use SSH keys to automate the process of logging in via SSH. Here is the following code to execute a script remotely.
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Try, ssh user#host sh path/run.sh